NYOJ33 蛇形填数

蛇形填数

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 3
描述
在n*n方陈里填入1,2,...,n*n,要求填成蛇形。例如n=4时方陈为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
输入
直接输入方陈的维数,即n的值。(n<=100)
输出
输出结果是蛇形方陈。
样例输入
3
样例输出
7 8 1
6 9 2
5 4 3
 
   
 
   
my cpp:
#include<stdio.h>
#include<string.h>//一直往一个方向走 
int main()
{
	 int n,i,j,a[102][102],m;//定义二维数组,尽量大一点
	 memset(a,0,sizeof(a));//给数组中各元素赋0,表示其还未赋值
	 while((scanf("%d",&n))!=EOF)
	 {
	 	m=1;
	 	a[0][n-1]=m;
	 	for(i=0,j=n-1;(m<n*n);)//对于每一个位置,有上、下、左、右四个方位,分别找到其可走的条件(注意是m<n*n)
	 	{
		 	while((a[i+1][j]==0)&&((i+1>=0&&i+1<n)&&(j>=0&&j<n)))//使用循环是为了在条件满足时一直沿一个方向走下去
						   i++;
			   m++;
			   a[i][j]=m;
			};
		 	while((a[i-1][j]==0)&&((i-1>=0&&i-1<n)&&(j>=0&&j<n)))
						   i--;
			   m++;
			   a[i][j]=m;
			};
		 	while((a[i][j+1]==0)&&((i>=0&&i<n)&&(j+1>=0&&j+1<n)))
						   j++;
			   m++;
			   a[i][j]=m;
		    }; 
		 	while((a[i][j-1]==0)&&((i>=0&&i<n)&&(j-1>=0&&j-1<n)))
		 	{
		 		j--;
		 		m++;
		 		a[i][j]=m;
		 	};
	 	}
	 	for(i=0;i<n;i++)//输出结果
	 			    for(j=0;j<n;j++)
	 	        printf("%d ",a[i][j]);
	 	    printf("\n");
	    }
	 return 0;
     }
 }
//如何记住上一次选择的方向,因为要优先保证与上一次方向相同。
 
   
    很明显,首先思路是要建立一个二维数组。
    这道题主要就是考了如何找到1至n*n这n*n个数所对应的二维数组的位置,一些比较高级的代码通常都会去找到每个数与其对应位置的序列号的数学关系,这样的代码编程需要较好的数学与算法应用能力,笔者暂时能力不够,所以从最简单的思路来做的,那就是一个一个按顺序增加赋值的同时,找到所需路径,这个似乎可以归于搜索一类。
    我的想法就是从初始位置,首先给一个初始方向,由于在路径中,我们不能后退,所以我们要想办法区分未赋值与已赋值的位置,我选择了子在最开始给整个二维数组赋0(因为被赋值后的位置上数值始终要大于0),这样就解决了第一个问题。然后就是怎样寻找可走路径,这个比较好想到,每个位置有四个方向,将所有点束缚在n*n的矩阵中,就限定了前进范围,然后最重要的就是保证在满足上述条件时,一直朝着一个方向走,直到到了角点处,此时要改变方向,不过很明显,只有一个方向可选,这样就可以在一个方向可走时把这一段放进一个循环,循环结束时必然到了一个角点,再判断方向即可继续走下去,直到这n*n个数都已被赋值。
   从而解决了这一问题。
   说起来这一题还是挺好想的,并没有一点思维陷阱,只要静下心来好好想一下解决方案就能很容易的解决了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值