poj2488

原题: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 30
struct 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值