PAT (Basic Level) Practice 1050 螺旋矩阵 (25 分)

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

输入格式:

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

输出格式:

输出螺旋矩阵。每行 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

思路: 

难点一:求出m、n的值, m、n的值即是整数N的差值最小的约数,且m>n。

难点二:存储螺旋矩阵,按照向右、向下、向左、向右的顺序进行存储,开始时将x设为1,y设为0,实际存储的位置是从a[1][1]开始的。具体代码实现如下。

代码实现:

#include 
using namespace std;

bool cmp(int a,int b){
    return a>b;//升序
}
int s[10010],a[10010][1010] = {0};
//放在函数内部会致使停止运行,a数组太大,最后一个测试点不能通过
int main() {

    int N,m,n,Min = 10001;
    scanf("%d",&N);
    for(int i = 0;i < N;i++)
        scanf("%d",&s[i]);
    sort(s,s+N,cmp);
    //求出m,n分别是多少,即求N的差值最小的公约数
    //且m>n
    for(int i = 1;i <= sqrt(N);i++){
        if(N%i == 0){
            if(N/i-i < Min){
                Min = N/i-i;
                n = i;
            }
        }
    }
    m = N/n;//m行n列
    int count = 0;
    int x = 1,y = 0;
    while(count < N)
    {
        while(y + 1 <= n && !a[x][y + 1])
            a[x][++y] = s[count++];
        while(x + 1 <= m && !a[x + 1][y])
            a[++x][y] = s[count++];
        while(y - 1 > 0 && !a[x][y - 1])
            a[x][--y] = s[count++];
        while(x - 1 > 0 && !a[x - 1][y])
            a[--x][y] = s[count++];
    }

    /*a[1][1]=s[0];
    int tot=0;
	int x=1,y=1;
    while(tot < m * n-1)
    {
        while(y + 1 <= n && ! a[x][y + 1])
            a[x][++y] = s[++tot];
        while(x + 1 <= m && !a[x + 1][y])
            a[++x][y] = s[++tot];
        while(y - 1 > 0 && !a[x][y - 1])
            a[x][--y] = s[++tot];
        while(x - 1 > 0 && !a[x - 1][y])
            a[--x][y] = s[++tot];
    }
    */
    for(int i=1;i<=m;i++){
            printf("%d",a[i][1]);
        for(int j=2;j<=n;j++){
                printf(" %d",a[i][j]);
        }
        printf("\n");

    }
    return 0;
}

 

你可能感兴趣的:(PAT)