Openjudge-NOI题库-蛇形填充数组
题目描述 Description
用数字1,2,3,4,...,n*n这n2个数蛇形填充规模为n*n的方阵。
蛇形填充方法为:
对于每一条左下-右上的斜线,从左上到右下依次编号1,2,...,2n-1;按编号从小到大的顺序,将数字从小到大填入各条斜线,其中编号为奇数的从左下向右上填写,编号为偶数的从右上到左下填写。
比如n=4时,方阵填充为如下形式:
输入输出格式 Input/output
输入格式:
输入一个不大于10的正整数n,表示方阵的行数.
输出格式:
输出该方阵,相邻两个元素之间用单个空格间隔。
输入一个不大于10的正整数n,表示方阵的行数.
输出格式:
输出该方阵,相邻两个元素之间用单个空格间隔。
输入输出样例 Sample input/output
样例测试点#1
输入样例:
4
输出样例:
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
思路:我先以一个5*5的例子开头吧,如下图所示是一个已经填充好的蛇形数组:
图中的kk根红线代表有kk次循环,kk=2*n-1
每次按照红线的箭头来存放数字,对于循环的次数i来说,如果i是单数,则数字存放是由左下往右上,如果i是双数,则数字存放是由右上往左下。
这里要分两种情况来讨论:
<1>:当循环是下图中的①部分时,每次循环的次数都会递增1,第一次循环是从1开始,第二次循环是2、3,第三次循环是4、5、6
那么对于每次循环的开始和止点,通过观察都可以得出一个普遍结论,当i是奇数时,循环次数为i次,a[i-j][j]就可以递增;当i是偶数,循环次数还是i次,a[j][i-j],也是递增
<2>:当循环是下图中的②部分时,每次循环的次数也是递增1,第一次循环是16、17、18、19,第二次循环是20、21、22,以此类推,每次需要循环的次数都是递减的,这时候循环的次数和循环的起止点都不和i<=n时一样了,这时候就需要重新寻找规律,我在这里定义了一个k来计算循环到达的层数,例如16、17、18、19这是第一层,这样就可以很方便地用k和n来控制循环次数,我得出了一个普遍公式:j从0开始一直到n-k循环,如果i是奇数,则每次递增a[i-j-k][j+k],如果i是偶数,则每次递增a[j+k][i-j-k]即可。
代码如下:
1 #include <stdio.h> 2 int main() 3 { 4 int n,i,j; 5 int kk; 6 int o=1;//用来改变数组的变量 7 int k=1; 8 int a[101][101]; 9 scanf("%d",&n); 10 kk=2*n-1;//控制总循环次数 11 for(i=0;i<=kk;i++) 12 { 13 /*===========================*///①部分 14 if(i%2==0&&i<n)//递增 15 { 16 for(j=0;j<=i;j++) 17 { 18 a[i-j][j]=o; 19 o++; 20 } 21 } 22 else if(i%2==1&&i<n)//递减 23 { 24 for(j=0;j<=i;j++) 25 { 26 a[j][i-j]=o; 27 o++; 28 } 29 } 30 /*===========================*///②部分 31 else if(i%2==0&&i>=n)//递增 32 { 33 for(j=0;j<n-k;j++) 34 { 35 a[i-j-k][j+k]=o; 36 o++; 37 } 38 k++; 39 } 40 else if(i%2==1&&i>=n)//递减 41 { 42 for(j=0;j<n-k;j++) 43 { 44 a[j+k][i-j-k]=o; 45 o++; 46 } 47 k++; 48 } 49 } 50 for(i=0;i<n;i++)//输出结果 51 { 52 for(j=0;j<n;j++) 53 { 54 printf("%d ",a[i][j]); 55 } 56 printf("\n"); 57 } 58 return 0; 59 }
我不怕千万人阻挡,只怕自己投降…