[ACM]A Knight's Journey DFS应用

Background
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?

Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.

Input

The input begins with a positive integer n in the first line. The following lines contain n test cases. Each test case consists of a single line with two positive integers p and q, such that 1 <= p * q <= 26. This represents a p * q chessboard, where p describes how many different square numbers 1, . . . , p exist, q describes how many different square letters exist. These are the first q letters of the Latin alphabet: A, . . .
Output

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be given on a single line by concatenating the names of the visited squares. Each square name consists of a capital letter followed by a number.
If no such path exist, you should output impossible on a single line.
Sample Input

3
1 1
2 3
4 3Sample Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

        很囧的一道题目,其实就是判断在制定的棋盘大小内是否会出现汉密尔顿回路,由于棋盘最大也才26格,DFS就行了,找到第一个解救输出答案,一直找不到就输出不可能.网上有的做法是从每个点都试一遍,其实完全没有必要,因为只要有的话就需要遍历每个点,此时每个点作为起点都能成功.唯一需要注意的是要记录路径,并且一个是'A'开头,一个是1开头,有点相应转换,最关键的还是需要注意尝试路径的顺序,不对的话会WA的....我反正试了几个顺序才对,莫非是题目理解错了?

 
 
  1. #include "iostream"
  2. using namespace std;
  3. //1,1肯定在回路中,所以只需要判断从1,1出发即可
  4. int p,q;
  5. int str[60];
  6. bool find1;
  7. bool a[30][30];
  8. const int xShift[8]={-2,-2,-1,-1,1,1,2,2};//顺序很重要....没有special judge
  9. const int yShift[8]={-1,1,-2,2,-2,2,-1,1};
  10. void Dfs(const int x,const int y,const int n){
  11.     //cout<<x<<" "<<y<<"...."<<n<<"......."<<endl;
  12.     if(n==p*q-1){
  13.         //puts("if");
  14.         for(int i=0;i<2*p*q-2;i+=2){
  15.             printf("%c%d",'A'+str[i]-1,str[i+1]);
  16.         }
  17.         printf("%c%d/n",'A'+x-1,y);
  18.         find1=true;
  19.     }else if(!find1){
  20.         //puts("else");
  21.         str[n*2]=x;str[n*2+1]=y;//record;
  22.         a[x][y]=false;
  23.         for(int i=0;i<8;i++){
  24.             int X=x+xShift[i],Y=y+yShift[i];
  25.             //cout<<X<<" .............. "<<Y<<endl;
  26.             if(0<X && X<=p && 0<Y && Y<=q && a[X][Y]){
  27.                 Dfs(X,Y,n+1);
  28.                 //cout<<X<<" .. "<<Y<<endl;
  29.             }
  30.         }
  31.         a[x][y]=true;
  32.     }
  33. }
  34. int main(){
  35.     int t,i,j,k;
  36.     scanf("%d",&t);
  37.     for(i=0;i<t;i++){
  38.         scanf("%d%d",&q,&p);
  39.         printf("Scenario #%d:/n",i+1);
  40.         find1=false;
  41.         memset(a,true,sizeof(a));
  42.         str[0]=str[1]=1;
  43.         Dfs(1,1,0);
  44.         if(!find1){
  45.             printf("impossible/n",i+1);
  46.         }
  47.         puts("");
  48.     }
  49.     return 0;
  50. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值