POJ_2488——骑士遍历棋盘,字典序走法

Description

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 3

Sample Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string>
 4 #include <cstring>
 5 //lexicographically first path
 6 //题目output中出现了以上几个单词
 7 //就是说骑士的移动步子是按照字典顺序来排列的
 8 //首先对列进行排序较小的在前面,然后按行进行排序也是较小的在前面 
 9 //我构造的xy坐标是按照SDL中的图形坐标,x往下递增,y往右递增
10 //转换成数学上的xy坐标就要先对列x做排序然后再对行y做排序 
11 int dirx[8]={-2,-2,-1,-1,1,1,2,2};
12 int diry[8]={-1,1,-2,2,-2,2,-1,1};
13 
14 int T,p,q,mark[27][27];
15 std::string way;
16 bool DFS(int x,int y,int step)
17 {
18    if(step==p*q)
19       {
20          return true;
21       }
22    for(int i=0;i<8;i++)
23       {
24          int dx=x+dirx[i];
25          int dy=y+diry[i];
26          if((dx>=1 && dx<=q) && (dy>=1 && dy<=p) && mark[dx][dy]!=1)
27             {
28                mark[dx][dy]=1;
29                //当找到路径才会插入操作,所以在main函数循环中不需要清空string 
30                if(DFS(dx,dy,step+1))
31                   {
32                      //在第0个位置插入1个字符
33                      //先插入数字然后再插入字母,否则顺序颠倒 
34                      way.insert(0,1,dy+'0');
35                      way.insert(0,1,dx+'A'-1);
36                      return true;   
37                   }
38                mark[dx][dy]=0;
39             }
40       }
41    return false;
42 }
43 int main()
44 {
45    scanf("%d",&T);
46    for(int i=1;i<=T;i++)
47       {
48          scanf("%d%d",&p,&q);
49          way.clear();//每次都要清空string
50          bool find=false;
51          for(int x=1;x<=q && !find;x++)
52             {
53                for(int y=1;y<=p;y++)
54                   {
55                      memset(mark,0,sizeof(mark));
56                      mark[x][y]=1;
57                      if(DFS(x,y,1))
58                         {
59                            //找到的话插入起始位置 
60                            way.insert(0,1,y+'0');
61                            way.insert(0,1,x+'A'-1);
62                            find=true;
63                            break;
64                         }
65                   }
66             }
67          std::cout<<"Scenario #"<<i<<":"<<std::endl;
68          if(find)
69             {
70                //整体输出就行
71                std::cout<<way<<std::endl<<std::endl;
72             }
73          else
74             printf("impossible\n\n");
75       }
76    return 0;   
77 }

 

posted @ 2013-07-12 14:37  瓶哥  Views(510)  Comments(0Edit  收藏  举报