东华大学2020考研计算机OJ题目解答分享——进阶篇(61)

61 螺旋方阵

问题描述 :

明明在上学的时候,参加数学兴趣班。在班上,老师介绍了一种非常有趣的方阵,称之为螺旋方阵。该方阵一共由n×n个正整数构成(我们称之为n阶螺旋方阵),即共有n行n列。

方阵中的数字从1开始递增,数字的排序规则是从左上角出发由1开始排序,并按顺时针方向旋进,即先排最外面的一圈,然后排里面的一圈,以此类推,直到排到最后一个数为止。

例如一个4阶的螺旋方阵,一共有4×4=16个正整数构成,数字从1递增到16,最后排出来的方阵如下:

1 2 3 4

12 13 14 5

11 16 15 6

10 9 8 7

明明回家后想自己动手构造这样的螺旋方阵。他从n=1开始构造,但是他发现当n越来越大时,螺旋方阵的复杂性就越高,然后构造出来的方阵就越容易出错。为了降低构造方阵的出错率,提高构造速度,明明就求助于你,请你帮他写一个程序,来构造螺旋方阵。 明明的问题可以归结为:给你一个正整数n,请你按题目描述中所述的方法,构造出n阶的螺旋方阵。

输入说明 :

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行仅有一个正整数n(1≤n≤10),即所要构造的螺旋方阵的阶数。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

输出说明 :

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个n阶的螺旋方阵,方阵中的数字用一个空格隔开,具体形式请参考输出样例。每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果之后没有空行。 注:通常,显示屏为标准输出设备。

输入范例 :

9
4

输出范例 :

1 2 3 4 5 6 7 8 9
32 33 34 35 36 37 38 39 10
31 56 57 58 59 60 61 40 11
30 55 72 73 74 75 62 41 12
29 54 71 80 81 76 63 42 13
28 53 70 79 78 77 64 43 14
27 52 69 68 67 66 65 44 15
26 51 50 49 48 47 46 45 16
25 24 23 22 21 20 19 18 17

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7


解题思路:

填充数组方法相当有规律。可以采用状态机,分为四个状态 r右 d下 l左 u上。显然初态从坐标[0][0]开始向右。

AC代码

#include<stdio.h>
#include<string.h>

int main(){
	int n;
	while(~scanf("%d",&n))
	{
		int a[n][n];
		memset(a,0,sizeof(a));
		a[0][0]=1;
		int x=0,y=0;
		char state='r';
		for(int i=2;i<=n*n;i++)
		{
			switch(state){
				case 'r':
					if(y+1==n||a[x][y+1]!=0)
					{
						state='d';
						x=x+1;
						a[x][y]=i;
					}
					else
					{
						y=y+1;
						a[x][y]=i;
					}
				break;
				case 'd':
					if(x+1==n||a[x+1][y]!=0)
					{
						state='l';
						y=y-1;
						a[x][y]=i;
					}
					else
					{
						x=x+1;
						a[x][y]=i;	
					}
				break;
				case 'l':
					if(y-1<0||a[x][y-1]!=0)
					{
						state='u';
						x=x-1;
						a[x][y]=i; 
					}
					else
					{
						y=y-1;
						a[x][y]=i;
					}
				break;
				case 'u':	
					if(x-1<0||a[x-1][y]!=0)
					{
						state='r';
						y=y+1;
						a[x][y]=i;
					}
					else
					{
						x=x-1;
						a[x][y]=i;
					}
				break;
			}
			
		}
		
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				printf("%d",a[i][j]);
				if(j==n-1)
				{
					printf("\n");
				}
				else
				{
					printf(" ");
				}
				
			}
			
		}
		printf("\n");	
	}	
} 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值