2015-06-05
問題簡述:
有一個 p*q 的棋盤,一個騎士(就是中國象棋裡的馬)想要走完所有的格子,棋盤橫向是 A...Z(其中A開始 p 個),縱向是 1...q。
原題鏈接:http://acm.tju.edu.cn/toj/showp1702.html
解題思路:
DFS:深搜把所有情況都考慮一遍,當騎士走出棋盤或走到原來走過的格子時,旅行失敗了;當騎士能一直走下去直到走過的格子數等於 p*q 時,旅行成功。
提交過程中一直有一個問題使這個代碼一直WA,最後才發現是 p、q輸入反了,先輸入的數是 q(也就是縱向的數字標號)。。。
源代碼:
1 /*
2 OJ: TOJ
3 ID: 3013216109
4 TASK: 1702.A Knight's Journey
5 LANG: C++
6 NOTE: DFS
7 */
8 #include <cstdio>
9 #include <cstring>
10
11 int n,p,q,flag;
12 int x[8]={-2,-2,-1,-1,1,1,2,2};
13 int y[8]={-1,1,-2,2,-2,2,-1,1};
14 char tmp[27]={"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
15 char ans1[27];
16 int ans2[27];
17 int visited[35][35];
18
19 bool dfs(int a,int b) {
20 if(!visited[a][b]) visited[a][b]=1;
21 else return false; //如果走到已經走過的棋盤,則失敗
22 ans1[flag]=tmp[a-1];
23 ans2[flag]=b;
24 flag++;
25 if(flag>=p*q) return true; //走完所有的格子,則成功
26 for(int i=0;i<8;i++) {
27 if(a+x[i]>0&&a+x[i]<=p&&b+y[i]>0&&b+y[i]<=q&&dfs(a+x[i],b+y[i]))
28 return true; //如果下一步不走出棋盤且能走完剩下的格子,則成功
29 }
30 visited[a][b]=0;
31 flag--; //回溯
32 return false; //不能成功的走完所有的格子,則失敗
33 }
34
35 int main()
36 {
37 scanf("%d",&n);
38 int i,j,k=1;
39 while(n--) {
40 printf("Scenario #%d:\n",k++);
41 scanf("%d %d",&q,&p);
42 flag=0;
43 memset(visited,0,sizeof(visited));
44 int solved=0;
45 for(i=1;i<=p;i++) {
46 for(j=1;j<=q;j++) { //遍歷所有可能的起點
47 if(dfs(i,j)) {
48 solved=1;
49 for(int l=0;l<p*q;l++)
50 printf("%c%d",ans1[l],ans2[l]);
51 printf("\n\n");
52 break;
53 }
54 }
55 }
56 if(!solved)
57 printf("impossible\n\n");
58 }
59 return 0;
60 }