题目:
巧摆螺旋阵~
我的理解:
这是一个比较经典的求值法问题了,曾经作为类似于此题的一道题,和南阳OJ系统中蛇形填数(一)差不多。这两道题时一种思想。重点是解决下标的转换问题。具体理解可参考代码中的注释。其中有一点要注意一下,在定义数组时一定要比题目要求的大一些,不然会莫名奇妙的报出一些超时错误,我就栽在这上面了。。
我的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAX_N 2000 //要注意此处,之前我定义的1000系统给报了超时错误,改了2000就好了。
using namespace std;
int a[MAX_N][MAX_N]; //该二维数组用来存放循环的数
int main()
{
freopen("D:/OJ/挑战程序设计竞赛/蛇形填数.txt","r",stdin);
int t,n,nn;
cin>>t; //t组测试数据
while(t-- != 0){
cin>>n;
nn = n; //之所以在此把n赋值给nn,是因为下面的填数循环会改变n的值,而遍历二维数组时又要用到n的值,所以copy一份给nn
int tag = 1;//被递增的值
int m = (n%3==0?n/3:(n/3+1));//判断边长为n时,循环的三角形个数
for(int i = 0;i<m;i++){
if(n == 1){ //n为1则直接存放1在数组里,然后跳出
a[0][0] = 1;
break;
}
for(int j = 0;j<n-1;j++){ //从左往右填数
a[i][j+i] = tag++;
}
for(int j = 0;j<n-1;j++){ // 从右上往左下填数
a[j+i][n-1-j+i] = tag++;
}
for(int j = 0;j<n-1;j++){ //从下往上填数
a[n-1-j+i][i] = tag++;
}
n = n-3; //第一层三角循环完后,将n-3代表第二层三角形的边长
if(n == 1){ //当最中心的三角形边长刚好为1时,则该处应为最后一个数,位置刚好在a[i+1][i+1]
a[i+1][i+1] = tag++;
break;
}
}
for(int i = 0;i<nn;i++){ //输出数组中的数
for(int j = 0;j<(nn-i);j++){
if(a[i][j] > 0){
cout<<a[i][j]<<" ";
}
}
cout<<endl;
}
}
return 0;
}