POJ 2488 A Knight's Journey

标准的DFS,只不过是坑爹的字典序坑到了无数人……

题目大意:

给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。

注意事项:

只有一条,那就是字典序!!!!!!!!


对于马的位置,DFS搜索时需要按这个顺序来:


       (对图片作者表示感谢)

这样搜出来的第一条路就是字典序最小的路了。

还有一条就是因为这条路可以走过棋盘上的所有的点,我们也就可以认为如果搜起点是A1 的这条路不成立的话就不用搜了,因为这条路到不了所有点也就是所有点到不了任一点了(自己想为什么……)。

下面是代码:

#include <stdio.h>
#include <string.h>
int p,q;
bool map1[30][30];
int a[100][2],cut,x[8]= {-1,1,-2,2,-2,2,-1,1},y[8]= {-2,-2,-1,-1,1,1,2,2};
bool DFS (int i,int j,int stepnum)
{
    map1[i][j]=true;
    a[stepnum][0]=i;
    a[stepnum][1]=j;
    if(stepnum==p*q)
    {
        return true;
    }
    for(int k=0; k<8; k++)
    {
        int ii=i+x[k];
        int jj=j+y[k];
        if(ii>=0&&ii<p&&jj>=0&&jj<q&&!map1[ii][jj])
        {
            if(DFS(ii,jj,stepnum+1))
            {
                return true;
            }
        }
    }
    map1[i][j]=false;
    return false;
}
int main()
{
    int t,in=0,i,j;
    scanf("%d",&t);
    while(t--)
    {
        in++;
        scanf("%d%d",&p,&q);
        memset(map1,0,sizeof(map1));
        if(p==1&&q==1)
        {
            printf("Scenario #%d:\n",in);
            printf("A1\n\n");
            continue;
        }
        if(p*q>26||p>=9||q>=9||p<=2||q<=2)
        {
            printf("Scenario #%d:\n",in);
            printf("impossible\n\n");
            continue;
        }
        int flat=0;
        for(i=0; i<q; i++)
        {
            if(DFS(0,i,1))
            {
                printf("Scenario #%d:\n",in);
                for(int k=1; k<=p*q; k++)
                {
                    printf("%c%d",a[k][1]+'A',a[k][0]+1);
                }
                printf("\n\n");
                flat=1;
                break;
            }
        }
        if(!flat)
        {
            printf("Scenario #%d:\n",in);
            printf("impossible\n\n");
        }
    }
    return 0;
}


posted @ 2013-08-19 10:20  、小呆  阅读(132)  评论(0编辑  收藏  举报