本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
输入格式:
输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 104,相邻数字以空格分隔
输出格式:
输出螺旋矩阵。每行 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
emmm,这个题一种简单的版本c老师讲过,就是行列数都是一样的,这样填充就比较简单了,因为我是要用四层for来填充每一圈,如何确定有几圈就显得挺重要的。
如果行列数相同的话,就是(n+1)/2圈,读者可以自行画一下,一目了然。
不过这个行列数不同的话怎么办呢?可以看出圈数应该是与最小的那个数有关的,也就是n。这样就可以去填充啦。
不过还要注意的问题是m和n的范围,敲的时候也没多想,敲完后,一看到1e8了,怎么也要超时把,竟然没超时,仔细一看原来远没有达到1e8,n最大也就可以到1e2把(个人理解) ,m最大可以到1e4,因为N如果是素数的话m==N。
还有我的填充方式是这样的
这样插入的话,会有重复的也有漏掉的,比如15的时候,中间很长这样就会导致两边重复给同一个方格复制,数太大也有可能会漏掉某一个,所以这就需要特殊判断一下(还好这个题输入的都是正数),因为这种填充方式是正确的,填充的顺序也是正确的,只要让他填充到正确的位置即可。
还有一种更好的方式
要整块代码也不知为啥贴不上,那么就把填充时候的代码贴上吧,其他的都还好。
for(int t=1;t<=(n+1)/2;t++)//填充
{
for(int i=t;i<=n-t;i++)
if(b[t][i]==0) b[t][i]=a[cnt++];
for(int i=t;i<=m-t;i++)
if(b[i][n-t+1]==0) b[i][n-t+1]=a[cnt++];
for(int i=n-t+1;i>t;i--)
if(b[m-t+1][i]==0) b[m-t+1][i]=a[cnt++];
for(int i=m-t+1;i>t;i--)
if(b[i][t]==0) b[i][t]=a[cnt++];
}
for(int i=1;i<=m;i++)//把没有填的格子填上
for(int j=1;j<=n;j++)
if(b[i][j]==0) b[i][j]=a[cnt++];
}