zoukankan      html  css  js  c++  java
  • B1050 螺旋矩阵

    本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;mn;且 mn 取所有可能值中的最小值。

    输入格式:

    输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 1,相邻数字以空格分隔。

    输出格式:

    输出螺旋矩阵。每行 n 个数字,共 m 行。相邻数字以 1 个空格分隔,行末不得有多余空格。

    输入样例:

    12
    37 76 20 98 76 42 53 95 60 81 58 93
    
     

    输出样例:

    98 95 93
    42 37 81
    53 20 76
    58 60 76

    最终AC的代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn = 10001;
    int a[maxn], b[maxn][maxn], N;
    
    bool cmp(int a, int b){
        return a>b;
    }
    
    void toSaveRow_1(int &i, int k, int left, int right){
        int j=left;
        for( ; i<N; i++){
            if(j<=right){
                b[k][j] = a[i];
                j++;
            }else{
                break;
            }
        }
    }
    
    void toSaveCol_1(int &i, int k, int down, int up){
        int j=down;
        for( ; i<N; i++){
            if(j<=up){
                b[j][k] = a[i];
                j++;
            }else{
                break;
            }
        }
    }
    
    void toSaveRow_2(int &i, int k, int right, int left){
        int j=right;
        for( ; i<N; i++){
            if(j>=left){
                b[k][j] = a[i];
                j--;
            }else{
                break;
            }
        }
    }
    
    void toSaveCol_2(int &i, int k, int up, int down){
        int j=up;
        for( ; i<N; i++){
            if(j>=down){
                b[j][k] = a[i];
                j--;
            }else{
                break;
            }
        }
    }
    
    int main(){
        int i, j, m, n, left, right, down, up;
        scanf("%d", &N);
        for(i=0; i<N; i++){
            scanf("%d", &a[i]);
        }
        n = (int)sqrt(N*1.0);
        while(N % n != 0) n--;
        m = N / n;
        sort(a, a+N, cmp);
        left = 0;
        right = n - 1;
        down = 0;
        up = m - 1;
        for(i=0; i<N; ){
            toSaveRow_1(i, down, left, right);
            toSaveCol_1(i, right, down+1, up-1); //列数 开始行 结束行 
            toSaveRow_2(i, up, right, left);
            toSaveCol_2(i, left, up-1, down+1);
            left++;
            right--;
            down++;
            up--; 
        }
        for(i=0; i<m; i++){
            for(j=0; j<n; j++){
                if(j!=0){
                    printf(" %d", b[i][j]);
                }else{
                    printf("%d", b[i][j]);
                }
            }
            printf("
    ");
        }
        return 0;
    }

    由于一开始未真正理解题意,所以在求m、n时写成了如下形式:

    n = sqrt(N);
    m = N / n;

    很显然,当N=14时,n=3,m=4;这直接导致了后面出现了死循环,从而出现了三个测试用例超时的现象。然而,我还以为自己后面求b[row][col]数组时出现了错误。当N=14时,n=2,m=7,此时才符合题意。

    此外,由于sqrt()函数的定义形式为double sqrt(double n);因此调用时应该符合标准形式,以免发生不必要的错误。故将上面的代码最终改为了以下形式。

    n = (int)sqrt(N*1.0);
    while(N % n != 0) n--;
    m = N / n;

    当然了,填充b[row][col]数组的过程可以写得更简洁些,优化后的代码为以下形式:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn = 10001;
    
    bool cmp(int a, int b){
        return a>b;
    }
    
    int main(){
        int i, j, m, n, left, right, down, up, row, col, N;
        scanf("%d", &N);
        n = (int)sqrt(N*1.0);
        while(N % n != 0) n--;
        m = N / n;
        int a[N+1], b[m+1][n+1];
        for(i=0; i<N; i++){
            scanf("%d", &a[i]);
        }
        sort(a, a+N, cmp);
        left = 0;
        right = n - 1;
        down = 0;
        up = m - 1;
        row = 0;
        col = 0;
        for(i=0; i<N; ){
            while(i<N){
                b[down][col] = a[i++];
                if(col<right) col++;    
                else{
                    row++;
                    down++;
                    break;
                }
            }
            while(i<N){
                b[row][right] = a[i++];
                if(row<up) row++;
                else{
                    col--;
                    right--;
                    break;
                }
            }
            while(i<N){
                b[up][col] = a[i++];
                if(col>left) col--;    
                else{
                    row--;
                    up--;
                    break;
                }
            }
            while(i<N){
                b[row][left] = a[i++];
                if(row>down) row--;
                else{
                    col++;
                    left++;
                    break;
                }
            }
        }
        for(i=0; i<m; i++){
            for(j=0; j<n; j++){
                if(j!=0){
                    printf(" %d", b[i][j]);
                }else{
                    printf("%d", b[i][j]);
                }
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    [03] html 中引入与使用css
    [04] 前端构建工具区别
    [04]测试框架杂谈
    [03] react 测试
    [02] 前端测试工具集锦
    [01]关于TDD、BDD和DDD的一些看法
    [04]JS获取文件大小方法
    [03]使用阿里RAP搭建前端Mock Server
    [1]区分event对象中的[clientX,offsetX,screenX,pageX]
    [02]a tag只为成button用时候设置href的办法
  • 原文地址:https://www.cnblogs.com/heyour/p/12230821.html
Copyright © 2011-2022 走看看