B1050 螺旋矩阵
Posted heyour
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了B1050 螺旋矩阵相关的知识,希望对你有一定的参考价值。
本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
输入格式:
输入在第 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; }
以上是关于B1050 螺旋矩阵的主要内容,如果未能解决你的问题,请参考以下文章