poj 2488 A Knight's Journey(暴力dfs 你懂的)

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

A Knight's Journey
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 24572   Accepted: 8305

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 <= p * q <= 26 题目数据量不是很大,可以直接暴力dfs求解,主要是保证输出第一个为最小字典序,这里我们控制遍历搜索时的顺序就可以了,这里主要体现在以下数组中:
int cy[]={-2,-2,-1,-1,1,1,2,2};
int cx[]={-1,1,-2,2,-2,2,-1,1};
这里cy数组的值为 {-2,-2,-1,-1,1,1,2,2} 因为cy为 输出串中的 A,B,C 故优先选择,然后cx {-1,1,-2,2,-2,2,-1,1} 一小一大的排列
这样就可以保证最小字典序
代码:
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 using namespace std;
 6 
 7 //这样设置这两个数组很好的保证了最后输出的序列是字典序
 8 int cy[]={-2,-2,-1,-1,1,1,2,2};
 9 int cx[]={-1,1,-2,2,-2,2,-1,1};
10 
11 int mark[30][30];
12 int flag=0;
13 
14 void dfs(int n,int m,int x,int y,int cnt)
15 {
16     int i,j,k;
17     if(flag)  //序列找到便不用在找
18     {
19         return;
20     }
21     if(cnt==n*m)  //找到序列进行输出
22     {
23         for(k=1;k<=n*m;k++)
24         for(i=1;i<=n;i++)
25         {
26             for(j=1;j<=m;j++)
27             {
28                 if(k==mark[i][j])
29                 {
30                     printf("%c%d",'A'-1+j,i);
31                 }
32             }
33         }
34         printf("\n");
35         flag=1;  //标记表示序列
36         return;
37     }
38     for(i=0;i<8;i++)
39     {
40         int dx=x+cx[i];
41         int dy=y+cy[i];
42         if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!mark[dx][dy])
43         {
44             mark[dx][dy]=cnt+1;  //标记这点的位置状态
45             dfs(n,m,dx,dy,cnt+1);  //进行下一个点的查找
46             mark[dx][dy]=0;  //回溯
47         }
48     }
49 }
50 
51 int main()
52 {
53     int t,k;
54     scanf("%d",&t);
55     for(k=1;k<=t;k++)
56     {
57         int n,m;
58         scanf("%d%d",&n,&m);
59         printf("Scenario #%d:\n",k);
60         if(n==1&&m==1)
61         {
62             printf("A1\n\n");
63             continue;
64         }else if(n==1||m==1)
65         {
66             printf("impossible\n\n");
67             continue;
68         }
69         memset(mark,0,sizeof(mark));
70         int i,j;
71         for(i=1;i<=n;i++)
72         {
73             for(j=1;j<=m;j++)
74             {
75                 mark[i][j]=1;
76                 flag=0;
77                 dfs(n,m,i,j,1);
78                 if(flag)
79                 {
80                     break;
81                 }
82                 memset(mark,0,sizeof(mark));
83             }
84             if(j<=m)
85             {
86                 break;
87             }
88         }
89         if(i>n)
90         {
91             printf("impossible\n");
92         }
93         printf("\n");
94     }
95     return 0;
96 }

 

posted @ 2013-05-30 21:03  crazy_apple  阅读(384)  评论(0编辑  收藏  举报