POJ 2488 A Knight's Journey

来源:互联网 发布:mac windows f1 编辑:程序博客网 时间:2024/06/06 03:37

题目大意:

给定一个p*q的棋盘(p行q列或者q行p列都行,我是理解为q行p列),一个Knight在该棋盘上行走(走日字),可以从棋盘的任意方格出发,要求不重复的走完所有的方格,输出字典序最小的行走路线。q行:A、B、C...,p列:1、2、3...p;题目连接:http://poj.org/problem?id=2488

解题思路:

一道经典的“骑士游历问题”,网上说是DFS水题,可我觉得还是有些难度。毕竟DFS学的不好。

由于题目要求是按照字典序输出行走路线,那么在深搜的时候对扩展节点的搜索顺序是有要求的,搜索顺序如下所示:



代码:

#include<iostream>#include<fstream>#include<iomanip>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>#include<set>#include<map>#include<queue>#include<stack>#include<string>#include<vector>#include<sstream>#include<cassert>using namespace std;#define LL __int64int p,q;int vis[30][30];int dx[]={-2,-2,-1,-1,1,1,2,2};  //搜索顺序有特殊要求int dy[]={-1,1,-2,2,-2,2,-1,1};int th=0;int step[30][2];   //记录行走的路线bool dfs(int x,int y,int num){    if(num==p*q){           //走完所有的方格        step[th][0]=x;        step[th++][1]=y+1;        return true;    }    vis[x][y]=1;    for(int i=0;i<8;i++){        int tmpx,tmpy;        tmpx=x+dx[i];        tmpy=y+dy[i];        if(tmpx>=0 && tmpx<q && tmpy>=0 && tmpy<p && !vis[tmpx][tmpy]){            if(dfs(tmpx,tmpy,num+1)){               step[th][0]=x;step[th++][1]=y+1;                return true;            }        }    }    vis[x][y]=0;    return false;}int main(){    int n;    scanf("%d",&n);    for(int k=1;k<=n;k++){        scanf("%d%d",&p,&q);        memset(vis,0,sizeof(vis));        int flag=0;        for(int i=0;i<q;i++){            for(int j=0;j<p;j++){                th=0;                if(dfs(i,j,1)){                    flag=1;                    break;                }            }            if(flag)                break;        }        printf("Scenario #%d:\n",k);        if(!flag){            printf("impossible\n");        }        else{            for(int i=th-1;i>=0;i--){                printf("%c%d",step[i][0]+'A',step[i][1]);            }            printf("\n");        }        if(k<n)            printf("\n");    }    return 0;}


0 0