poj2488

来源:互联网 发布:淘宝新店卖啥好 编辑:程序博客网 时间:2024/06/16 13:46

原题:http://poj.org/problem?id=2488

题意是选择从任意位置开始以象棋中马的走法遍历,如能够遍历到所有的点则,输出路径;

理解:

(1)按照dfs进行深搜,如果按照跳马的规则无路可走而棋盘还没有全部遍历完时,则要撤销这一步,让这一步重新标记为未被访问的状态;

(2)当有多条路径可以遍历完时,按照字典的顺序输出字母最小的那条路,这时应该考虑到A1这个点,无论怎样的路径遍历完整个棋盘时都要经过A1这个点,所以我们从这个点开始搜索;


注:假设骑士起始位置在途中D4处,搜索的顺序如图1~8。

代码:

#include<cstdio>#include<cstring>using namespace std;const int dx[8]={-1,1,-2,2,-2,2,-1,1};const int dy[8]={-2,-2,-1,-1,1,1,2,2};//x表示数字的坐标,y表示字母的坐标#define Max 30struct way{    int x;    char y;}step[Max];int t,p,q;bool flag,vis[Max][Max];void dfs(int x,int y,int cnt){    vis[x][y]=false;    step[cnt].x=x;    step[cnt].y=y+'A'-1;    if(cnt==p*q)//遍历完成    {        flag=true;        return ;    }    for(int i=0;i<8;i++)        {            int nx=x+dx[i];            int ny=y+dy[i];            if(nx>0&&nx<=p&&ny>0&&ny<=q&&!flag&&vis[nx][ny])                {                    dfs(nx,ny,cnt+1);                    vis[nx][ny]=true;//不能遍历完,这一步标记未被访问                }        }}int main(){    scanf("%d",&t);    for(int c=1;c<=t;c++)    {        flag=false;        scanf("%d%d",&p,&q);        memset(vis,true,sizeof(vis));        dfs(1,1,1);        printf("Scenario #%d:\n",c);        if(flag)        {            for(int i=1;i<=p*q;i++)            {                printf("%c%d",step[i].y,step[i].x);            }            printf("\n");        }        else            printf("impossible\n");        if(c!=t)            printf("\n");    }    return 0;}

1 0
原创粉丝点击