婴儿背带好还是腰凳好:求一个回转填数的pascal程序

来源:百度文库 编辑:高考问答 时间:2024/04/30 16:21:10
可以找到c语言的可我又看不懂,
请高手指教。

输出如下形式的数组:如 n=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

程序若能有解释和算法分析更好了
谢谢各位

反驳一下楼上先!我是PASCAL的FANS,我不同意PASCAL被淘汰的说法!目前的Delphi不就是基于PASCAL语言的吗?

这个因该是信息学奥赛题吧?以前见到过.

我的思路是这样的:建立一个二维数组,输入n后,在这个数组中按照螺旋次序填写.填写完毕过后再把数组打印出来.

1.建立一个数组,我们规定n<=10
a:array[0..10,0..10] of integer;

2.其他变量
i,j :integer; {i为横坐标,j为纵坐标}
k :integer; {计数器.每填一个空,k增1}
n,m :integer; {m为n*n的值,格子的总数}
现在的问题是:怎样来填这个数组.

我们具体来看一下:首先从第一个格子开始出发,向右走.走了n个格子后,向下拐.也就是初始时
k=1;
i=1;j=1;
然后一直
a[i,j]:=k;
i:=i+1;
k:=k+1;
j保持不变.直到i=n时,向下拐
a[i,j]:=k;
j:=j+1;
k:=k+1;
i保持不变.

问题又来了,我们怎么知道什么时候拐弯呢?
而且再拐弯的时候就变成了i:=i-1;.我们又怎么知道什么时候'+'什么时候'-'呢?

再一想,其实是有规律可循的~i,j的变化是交替进行的.先不看增减,最先是i在变,过后必然是j变化,再下来必然又是i变化...
我们在看看增减情况,也是交替进行的.我们先只看i最初是增,下一次轮到i变化的时候必然是减,再下一次轮到i变化必然又是增...

这样的思路,我们可以用一个二重循环来控制.

外层循环是个空壳,包含了两个内层循环.内层的两个循环是并列的,分别控制i,j的变化.
因为循环次数是变化的,所以我们采用repeat和while循环.

我们再定义变量
bi,bj :boolean;
bi,bj分别控制i,j的增减情况.当bi为true时i增加,当bi为false时i减少.

m:=n*n;
i:=1;j:=1;
k:=1;
bi:=true;bj:=true;
repeat {外层循环}
while k<=m and (当前格子合法) do {内层循环1,控制i}
begin
a[i,j]:=k;
k:=k+1;
if bi then i:=i+1 else i:=i-1;
end;
if bi then i:=i-1 else i:=i+1; {i退格.因为循环是由于格子不合法而退出的,因而要让i回到合法的那个格子}
if bj then j:=j+1 else j:=j-1; {j前进.因为如果不前进,下一个循环进入时就当前的格子,是不合法的}
bi:=not bi;
while k<=m and (当前格子合法) do {内层循环2,控制j}
begin
a[i,j]:=k;
k:=k+1;
if bj then j:=j+1 else j:=j-1;
end;
if bj then j:=j-1 else j:=j+1; {j退格}
if bi then i:=i+1 else i:=i-1; {i前进}
bj:=not bj;
until k>m;

现在问题又来了,如何来判断当前的格子是否合法?

方法有很多,我用个比较没有技术含量的方法来检验.不知你注意到没有,我开数组的时候是从0开始的.也就是在合法的格子周围还有一圈空格子!我们就可以利用这一圈格子做一个"围墙".

首先用fillchar或for循环将数组全部赋值为0.
我们规定,只有格子为0才可以填写,否则就不合法.那么,只要将我们的"围墙"赋值为1或其他数字就可以了.也就是
while k<=m and a[i,j]=0 do
... ...
至于怎么做这个围墙,就自己想办法了,对你应该比较简单了.

然后就是打印,注意不要把"围墙"打印出来就是了.

核心代码已经写出来了,我没有验证.思路因该没有问题的,剩下的工作就看你组织代码的能力了.

pascal是一种已经被淘汰的语言。
这个程序需要设置许多变量,如果有兴趣,还是研究C语言比较好。