实验十二(2018)E. 实验8_11_旋转矩阵

这题和实验十一(2018)(优化!)E. 实验8_10_蛇形矩阵可以说是非常相似了,应该能想到是自动机。
试了一下枚举类型,非常合适并不关心常量值是多少,只是用来区分的情况,写起来很简洁

纸上画一画,从(0,0)开始,先向右走n个,再向下走n-1个,再向左走n-1个,再向上走n-2个,再向右走n-2个……循环
可以发现就第一次比较特殊,走了n次,所以我们把第一次单独拿出来赋值(第一轮for)。
注意在循环结束后,num和j还会自加一次,num是正确的,j则要自减一次。

之后进入自动机
circle标记的是走过的边数,由上面推算可知,每走过两边上限就会减一
times标记要走的次数,i,j是坐标,max_times保存上一轮的最大次数,方便times在变成零后恢复和控制上限
自动机以向下开始(向右的被手动走过了),采用的是“先移动,再赋值”的策略,当times变成1时说明这是最后一次了(因为是先移动再赋值,times的自减在后面),要按规律调换方向
times归零时, 走过的边数circle++。如果已经走了两边(circle==2),那么上限max_times要减一。每次times归零时,都要把它还原成max_times。
总的来说比蛇形矩阵要简单。

#include <stdio.h>
enum {RIGHT,DOWN,LEFT,UP};

int main(int argc, char const *argv[])
{
	int n,a[100][100],i=0,j=0,num;
	int state=DOWN;
	scanf("%d",&n);
	int circle=0,times=n-1,max_times=n-1;
	
	for(num=1;num<=n;num++,j++)
		a[i][j]=num;
	j--;

	for(;num<=n*n;num++)
	{	
		switch(state)
		{
			case RIGHT:
				j++;
				if(times==1) state=DOWN;
				break;
			case DOWN:
				i++;
				if(times==1) state=LEFT;
				break;
			case LEFT:
				j--;
				if(times==1) state=UP;
				break;
			case UP:
				i--;
				if(times==1) state=RIGHT;
				break;
		}
		
		a[i][j]=num;
		times--;

		if(times==0)
			{
				circle++;
				if(circle==2)
				{
					circle=0;
					max_times--;
					times=max_times;
				}
				else times=max_times;
			}
	}
	
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			printf("%d%c",a[i][j],j!=n-1?' ':'\n');
	return 0;
}

题目描述
问题描述:
旋转矩阵是一个nn的矩阵,将整数1到nn按照旋转的方式顺序装入一个n*n的旋转矩阵中,样例分别为5阶和10阶旋转矩阵:

输入与输出要求:
输入一个整数n,代表旋转矩阵的阶数,n的范围是1—100。输出旋转矩阵。每行的每个元素用空格分隔,注意最后一个数的后面为换行符。

程序运行效果:
Sample 1:
5

1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample 2:
10

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值