蛇形填数

题目:
在n*n的方阵里填入1,2,3,......,n*n ,要求填成蛇形。例如, n = 4时候方阵为:

10  11  12  1
9   16   13  2

8   15   14   3
7    6     5    4

上面的方阵中 , 多余的空格是为了便于观察,不必严格输出。n≤ 8 .

分析: 类比着在数学上的矩阵,我们可以用一个二维数组来存题目中的方阵,只需要声明一个二维数组就可以获得一个方阵,在声明时候,二维数组比一定非要是n*n的,也可以声明为m * n的矩阵。
    从一开始依此填写。设“笔”的坐标为(x,y),则一开始x = 0 , y = n -1 ,即从第零行第 n-1 列开始,我们用 n = 4 为例子来说,这个“笔”的轨迹是:下  下  下  左  左  左  上   上  上  右   右  下  下  左 上 。总之,先是下到不能填为止,然后是左,再接着是上,最后是右 。 不能填就是再走就会出界的情况(例如 4 -> 5),或者再走再走就要走到前边我们填过的格子,(例如12->13)。如果把所有的格子全都初始化为 0 ,我们就可以方便的加以判断。
    下面我们来上代码看看是不是很难以理解:
#include<iostream>
#include<cstdio>
#include<string.h>
#define maxn 20
int a[maxn][maxn];
using namespace std;
int main(){
	int n , x , y , tot = 0 ;
	scanf("%d",&n);
	memset(a , 0 , sizeof(a));
	tot = a[x = 0][y = n - 1] = 1 ;
	while(tot < n * n){
		while(x + 1 < n && !a[x+1][y])    //注意,这里的!a[x+1][y] 等价于a[x+1][y] == 0,这样是简写 
		a[++x][y] = ++tot ;
		while(y - 1 >= 0 && !a[x][y-1])
		a[x][--y] = ++tot ;
		while(x - 1 >= 0 && !a[x-1][y])
		a[--x][y] = ++ tot ;
		while(y + 1 < n && !a[x][y+1])
		a[x][++y] = ++tot ; 
	}
	for(x = 0 ; x < n ; x ++){
		for(y = 0 ; y < n ; y ++){
			printf("%3d",a[x][y]);
		}
		printf("\n");
	}
	return 0 ;
} 

注释:上边的四条while判断语句有点儿让人难以理解,但是他们十分相似,因此我在这里就只介绍其中的一条了:我来介绍第一条while语句吧,不断的往下走,并且开始填数。        
    我们开始时候的原则还是先开始判断再移动的,而不是发现走不通再回来。这样我们只要预判,也就是判断是不是会越界,以及如果继续走会不会走到我们填过数字的格子了。  
    越界我们需要判断x+1<n,因为y的值并没有修改,下一个格子是(x+1,y),因此只需要a【x+1】【y】 == 0 也就是我们简写的  !a【x+1】【y】。
    可能还有些人会发现这里边有一个潜在的bug   如果越界,x+1 会等于n ,a【x+1】【y】将无法访问,但是不用担心,因为我们在链接的时候用的是  &&  ,这是个短路运算符  ,  也就是说,如果x+1<n为假,我们就不会计算“!a【x+1】【y】”也就是说不会越界!~!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值