首页 > 其他 > 详细

【OI】蛇形填数题的深入探究

时间:2019-07-21 15:03:26      阅读:94      评论:0      收藏:0      [点我收藏+]

题目:在 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<=8)。

 

解:

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define maxn 20
 5 int a[maxn][maxn];
 6 
 7 int main ()
 8 {
 9     int n , x , y , tot = 0;
10     scanf("%d",&n);
11     memset(a,0,sizeof(a));
12     tot = a[x = 0][y = n-1] = 1;
13     
14     while (tot < n*n)
15     {
16         while (x+1<n && !a[x+1][y])    a[++x][y] = ++tot;
17         while (y-1>=0 && !a[x][y-1]) a[x][--y] = ++ tot;
18         while (x-1>=0 && !a[x-1][y]) a[--x][y] = ++tot;
19         while (y+1<n && !a[x][y+1])    a[x][++y] = ++tot;
20         
21     }
22     
23     for (x = 0;x < n;x++)
24     {
25         for (y = 0;y < n;y++)
26         {
27             printf("%3d",a[x][y]);  //输出和例题一样的格式
28         }
29         printf("\n");
30     }
31     
32     return 0;
33 }

下面对一些细节进行探究:

  一、二维数组的数学抽象

    由于我们无法控制鼠标的位置,我们只能通过平面的坐标系来定位每一个数的位置,在顺次输出几个。这就涉及到了平面坐标系在C语言中的抽象,很显然的,我们使用二维数组。

   技术分享图片

    每一个格子就是一个坐标,这样抽象的好处是我们无需考虑其如何输出,只需要考虑我们如何赋值即可。

    另外的一个技巧是:将整个数组初始化为0,这样0就代表是该坐标位置未被占去的状态,可以用!a[x][y}是否为1来判断。并且,无论格子内填了什么,!a[x][y]的值都会是0。

 

  二、简化运算符的使用

    就像书上说的一样,

    tot = a[x = 0][y = n-1] = 1; 

    这句话包含了很大的信息量。不仅使得代码变得简洁,而且没有使程序的易读性丧失。

  三、短路运算符的妙用

    当你不能避免某一条语句会导致下标溢出的时候,使用短路运算符可以很好的解决问题。就比如将!a[x+1][y]放入&&的后面,即使x+1>=n也不会使得下标溢出。

   四、细节问题

    注意观察变量的情况。如果tot的初始值为1,那么下面的句子就要使用tot++。

 

来自:《算法竞赛入门经典》--紫皮书

【OI】蛇形填数题的深入探究

原文:https://www.cnblogs.com/nowonder/p/snake-like-fill-in.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!