蛇形填数,我觉得它是C语言很有趣的的一种算法,也是对while循环一个很经典的应用。
实例如图:
但是这是怎么实现的呢? 在《算法入门经典(第二版)》中,有对蛇形填数的介绍。
其中代码如下:(注:不是书上原代码,有改动)
#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;
int a[100][100];
int main()
{
int n,x,y,tot;
cin>>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][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("%-5d",a[x][y]);
cout<<endl;
}
return 0;
}
这段代码表现了c语言的简洁性,先判断后移动,从右上到右下,再从右下到左下,再从左下到左上,再从左上到右上,然后再这样循环下去,其实挺佩服这几个while循环,写的真是恰到好处,没有一点多的东西,看的很舒服。
其实,这就是蛇形填数的一个模板,用这个模板,其他的和蛇形填数类似的题都和这个有异曲同工的感觉。
如 poj 3752 这道题:
字母旋转游戏
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8541 | Accepted: 3221 |
Description
给定两个整数M,N,生成一个M*N的矩阵,矩阵中元素取值为A至Z的26个字母中的一个,A在左上角,其余各数按顺时针方向旋转前进,依次递增放置,当超过26时又从A开始填充。例如,当M=5,N=8时,矩阵中的内容如下:
A B C D E F G H
V W X Y Z A B I
U J K L M N C J
T I H G F E D K
S R Q P O N M L
Input
M为行数,N为列数,其中M,N都为大于0的整数。
Output
分行输出相应的结果
Sample Input
4 9
Sample Output
A B C D E F G H I
V W X Y Z A B C J
U J I H G F E D K
T S R Q P O N M L
比较坑的地方在于输出字符前还要三个空格,万万没想到。还有在从“z”到“a”时,计算要认真点。
#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;
int a[1000][1000];
int main()
{
int n,m,x,y,tot=1;
char c;
cin>>m>>n;
memset(a,0,sizeof(a));
c='A';
a[x=0][y=0]='A';
while (tot<n*m)
{
while (y+1<n && !a[x][y+1])
{
if (c>=90)
c=c-26;
a[x][++y]=++c;
tot++;
}
while (x+1<m && !a[x+1][y])
{
if (c>=90)
c=c-26;
a[++x][y]=++c;
tot++;
}
while (y-1>=0 && !a[x][y-1])
{
if (c>=90)
c=c-26;
a[x][--y]=++c;
tot++;
}
while (x-1>0 && !a[x-1][y])
{
if (c>=90)
c=c-26;
a[--x][y]=++c;
tot++;
}
}
for (x=0;x<m;x++)
{
for (y=0;y<n;y++)
printf(" %c",a[x][y]);
cout<<endl;
}
return 0;
}
记住tot=1,而不是0。
蛇形填数如果用了这个模板,我相信一定会变得简单的。