POJ2488(骑士遍历)【dfs个人第一题!】

    dfs个人第一题,费尽千辛万苦,终于AC,一AC解万愁。果然自己亲自敲代码的过程学到不少。必作一总结。

    先附代码,修改比较多,so,比较丑。

   

#include<stdio.h>
#include<string.h>
int pan[30][30];
int fa[1000][2];
int count;
char alp[30]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int dfs(int i,int j,int cnt,int n)
{
    if(cnt==n){fa[cnt][0]=i;fa[cnt][1]=j;return 1;}
    fa[cnt][0]=i;fa[cnt][1]=j;
    pan[i][j]=0;
    if(i-1>0&&j-2>0&&pan[i-1][j-2]==1)
        {
           // pan[i-1][j-2]=0;
            if(dfs(i-1,j-2,cnt+1,n))
               {return 1;}
            //else pan[i-1][j-2]=1;
        }
    if(i+1>0&&j-2>0&&pan[i+1][j-2]==1)
        {
           // pan[i+1][j-2]=0;
            if(dfs(i+1,j-2,cnt+1,n))
               {return 1;}
            //else pan[i+1][j-2]=1;

        }
    if(i-2>0&&j-1>0&&pan[i-2][j-1]==1)
         {
            // pan[i-2][j-1]=0;
             if(dfs(i-2,j-1,cnt+1,n))
                {return 1;}
            // else pan[i-2][j-1]=1;

        }
    if(i+2>0&&j-1>0&&pan[i+2][j-1]==1)
          {
             // pan[i+2][j-1]=0;
              if(dfs(i+2,j-1,cnt+1,n))
                {return 1;}
              //else pan[i+2][j-1]=1;
          }
    if(i-2>0&&j+1>0&&pan[i-2][j+1]==1)
         {
             //pan[i-2][j+1]=0;
             if(dfs(i-2,j+1,cnt+1,n))
                {return 1;}
             //else pan[i-2][j+1]=1;
        }
    if(i+2>0&&j+1>0&&pan[i+2][j+1]==1)
           {
              // pan[i+2][j+1]=0;
               if(dfs(i+2,j+1,cnt+1,n))
                  {return 1;}
               //else pan[i+2][j+1]=1;
           }
    if(i-1>0&&j+2>0&&pan[i-1][j+2]==1)
        {
            //pan[i-2][j+2]=0;
            if(dfs(i-1,j+2,cnt+1,n))
              {return 1;}
            //else pan[i-2][j+2]=1;

        }
    if(i+1>0&&j+2>0&&pan[i+1][j+2]==1)
        {
           // pan[i+1][j+2]=0;
            if(dfs(i+1,j+2,cnt+1,n))
              {return 1;}
           // else pan[i+1][j+2]=1;
        }
    pan[i][j]=1;return 0;
}
int main()
{
    int case_num;
    scanf("%d",&case_num);
    int qq=1;
    for(;qq<=case_num;qq++)
    {
        int p,q;
        scanf("%d%d",&p,&q);
        if(p==1&&q==1)
        {
            printf("Scenario #%d:\n",qq);
            printf("A1\n");
            printf("\n");
            continue;
        }
           memset(pan,0,sizeof(pan));
           memset(fa,0,sizeof(fa));
           for(int i=1;i<=p;i++)
             for(int j=1;j<=q;j++)
               pan[i][j]=1;
        int ans=dfs(1,1,1,p*q);
        if(ans)
        {
            printf("Scenario #%d:\n",qq);
            for(int i=1;i<=p*q;i++)
                printf("%c%d",alp[fa[i][1]-1],fa[i][0]);
            printf("\n\n");
        }
        else
        {
            printf("Scenario #%d:\n",qq);
            printf("impossible\n\n");
        }
    }
    return 0;
}


     几点关键总结:

    1.

       先从基本的说起。dfs的思路,其实可以更进一步改进代码质量,详情见此题相关discuss。自己分八个dfs代码长度弄的其实比较长。

       单纯的遍历其实有好多判断方法,自己受LRJ代码风格影响,一般习惯用cnt与n的比较,当n==cnt时一般作为自己的判断条件。见网上还有人直接for()之后若无满足情况自动return false;

    2.

       自己真正不会的地方在于打印路径。

       最开始的思路是建了全局变量fa[MAX][2],可dfs每次过程中都会改变fa的值,并且自己建立的全局变量count的值也会在每次调用中改变。

       通过自己的代码中注释的部分也能看出自己的思路变化过程。

       后来一系列改进,参考网上某大神思路,

       fa[cnt][0]=i;fa[cnt][1]=j;

       用上述这种形式,cnt是当前,解决了我一个最大的疑问,这样的话每次遍历都会修改fa的值,而不至于像上次count那样一直累加。

       最后强调一点若最后不满足的话,要 pan[i][j]=1;return 0; 再把pan[i][j]的标记改回来。

  3.

     PS:自己的推判是正确的,每次若能遍历完,必可从A1开始。

     PS:字典序!

     PS:题目的输出有两个空格!

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值