蛇形填数

#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define LL long long
int main()
{
  int a[15][15];
  int n;
  while(scanf("%d",&n))
  {
      memset(a,0,sizeof(a));
      int l,r;
      int num;
      a[l=1][r=n]=num=1;
      while(num<n*n)
      {
        while(l+1!=n+1&&!a[l+1][r]) {a[++l][r]=++num;}
        while(r-1!=0&&!a[l][r-1]) {a[l][--r]=++num;}
        while(l-1!=0&&!a[l-1][r]) {a[--l][r]=++num;}
        while(r+1!=n+1&&!a[l][r+1]) {a[l][++r]=++num;}
      }
      for(int i=1;i<=n;i++)
      {
          for(int j=1;j<n;j++)
            printf("%2d ",a[i][j]);
            printf("%2d\n",a[i][n]);
      }
   }
  return 0;
}

我们从1开始依次填写。设“笔”的坐标为(x,y),则一开始x=1,y=n。

然后先是下,到不能填了为止,然后是左,接着是上,最后是右。

“不能填是指在走就出界,或者再走就要走到以前填过的格子。如果我们把所有

的格子初始化为0,就能很方便地加以判断。

(此处分析很重要,有时候不要感觉不能一口气敲出来就不敲了,有时候灵感会在一点点的敲代码的

时候涌现出来)。

此外,自己敲的代码不够简洁,改了一下,按照下面的改几处,可以使代码比较简洁,且保持了代码的可读性。

首先,赋值x=1和y=n后马上要把它们作为a数组的下标,因此可以合并完成;num和a[1][n]都要赋值1,也可以合并完成。

另外那四天while语句,起初自己写的代码比较麻烦,是用了”悔棋“的思想敲的,这里要注意是用”预判“的思想。

例如第一个while语句,我们的原则是:先判断,再移动,而不是走一步以后发现越界了再退回来。这样,我们需要

进行“预判”,即是否越界,以及如果继续往下走会不会到达一个已经填过的格子。越界只需判断l+1<n+1,因为r的值没有修改;

下一个格子是(l+1,r),因此只需a[l+1][r]==0,简写成!a[l+1][r](这个简写也要注意,简洁性).

(特别注意这里的用l+1进行预判,自己起初敲的代码,用的是“悔棋”的思想,比较麻烦,注意这个“预判”的思想)。

自己的代码,改良版。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值