這道題主要是寫一個圖的遍歷。由於題目中要求是最短路徑,因此採用的是寬度優先遍歷。原本是想縮短運行時間而採用頭尾同時使用bfs算法,但奈何我的水平有限而未能實現。因此本題代碼中使用就是最直接的bfs算法。因爲寫這段代碼時比較匆忙,因此代碼應該還有較大的優化空間。c++
1 #include <bits/stdc++.h>
2
3 using namespace std; 4
5 /******************* 6 UVa439 騎士的移動 7 *******************/
8
9 struct Node{ 10 //x1列 x2行 k是走到這個點須要的步數
11 int x1, x2, k; 12 Node(int x = 0, int y = 0, int weight = 0):x1(x), x2(y), k(weight){} 13 bool equal(Node& n){ 14 return (x1 == n.x1 && x2 == n.x2); 15 } 16 }; 17
18 int k = 0; 19 int buf[7][7]; 20 queue<Node> q1; 21
22 int char_to_int(char ch){ 23 return ch-96; 24 } 25
26 //尋找下一個位置而且將結構體入隊而且修改棋盤訪問狀態
27 int next(Node& n, Node& end){ 28 if(n.x1 + 2 <= 8 && n.x2 + 1 <= 8 && !buf[n.x2][n.x1 + 1]){ 29 Node n1(n.x1 + 2, n.x2 + 1, n.k+1); 30 if(n1.equal(end)){ 31 printf("%d", n1.k); 32 return 1; 33 }else{ 34 q1.push(n1); 35 buf[n1.x2-1][n1.x1-1] = 1; 36 } 37 } 38 if(n.x1 + 1 <= 8 && n.x2 + 2 <= 8 && !buf[n.x2 + 1][n.x1]){ 39 Node n1(n.x1 + 1, n.x2 + 2, n.k+1); 40 if(n1.equal(end)){ 41 printf("%d", n1.k); 42 return 1; 43 }else{ 44 q1.push(n1); 45 buf[n1.x2-1][n1.x1-1] = 1; 46 } 47 } 48 if(n.x1 - 1 >= 1 && n.x2 + 2 <= 8 && !buf[n.x2 + 1][n.x1 - 2]){ 49 Node n1(n.x1 - 1, n.x2 + 2, n.k+1); 50 if(n1.equal(end)){ 51 printf("%d", n1.k); 52 return 1; 53 }else{ 54 q1.push(n1); 55 buf[n1.x2-1][n1.x1-1] = 1; 56 } 57 } 58 if(n.x1 - 2 >= 1 && n.x2 + 1 <= 8 && !buf[n.x2][n.x1 - 3]){ 59 Node n1(n.x1 - 2, n.x2 + 1, n.k+1); 60 if(n1.equal(end)){ 61 printf("%d", n1.k); 62 return 1; 63 }else{ 64 q1.push(n1); 65 buf[n1.x2-1][n1.x1-1] = 1; 66 } 67 } 68 if(n.x1 + 1 <= 8 && n.x2 - 2 >= 1 && !buf[n.x2 - 3][n.x1]){ 69 Node n1(n.x1 + 1, n.x2 - 2, n.k+1); 70 if(n1.equal(end)){ 71 printf("%d", n1.k); 72 return 1; 73 }else{ 74 q1.push(n1); 75 buf[n1.x2-1][n1.x1-1] = 1; 76 } 77 } 78 if(n.x1 + 2 <= 8 && n.x2 - 1 >= 1 && !buf[n.x2 - 2][n.x1 + 1]){ 79 Node n1(n.x1 + 2, n.x2 - 1, n.k+1); 80 if(n1.equal(end)){ 81 printf("%d", n1.k); 82 return 1; 83 }else{ 84 q1.push(n1); 85 buf[n1.x2-1][n1.x1-1] = 1; 86 } 87 } 88 if(n.x1 - 1 >= 1 && n.x2 - 2 >= 1 && !buf[n.x2 -3][n.x1 - 2]){ 89 Node n1(n.x1 - 1, n.x2 - 2, n.k+1); 90 if(n1.equal(end)){ 91 printf("%d", n1.k); 92 return 1; 93 }else{ 94 q1.push(n1); 95 buf[n1.x2-1][n1.x1-1] = 1; 96 } 97 } 98 if(n.x1 - 2 >= 1 && n.x2 - 1 >= 1 && !buf[n.x2 - 2][n.x1 - 3]){ 99 Node n1(n.x1 - 2, n.x2 - 1, n.k+1); 100 if(n1.equal(end)){ 101 printf("%d", n1.k); 102 return 1; 103 }else{ 104 q1.push(n1); 105 buf[n1.x2-1][n1.x1-1] = 1; 106 } 107 } 108 return 0; 109 } 110
111 void solve(Node n1, Node n2){ 112
113 for(;;){ 114 //尋找下一個位置
115 if(next(n1, n2)){ 116 break; 117 }else{ 118 n1 = q1.front(); q1.pop(); 119 continue; 120 } 121 } 122 return; 123 } 124
125 int main() 126 { 127 char x = 0; 128 int y = 0; 129 memset(buf, 0, sizeof(buf)); 130
131 //輸入起使位置
132 cin >> x; 133 cin >> y; 134 Node start = Node(char_to_int(x), y, 0); 135 buf[y-1][char_to_int(x)-1] = 1; 136 //輸入終止位置
137 cin >> x; 138 cin >> y; 139 Node end = Node(char_to_int(x), y, 0); 140 if(start.equal(end)){ 141 printf("0"); 142 return 0; 143 } 144 solve(start, end); 145 return 0; 146 }
這段代碼的主要思路就是使用bfs算法遍歷圖,同時記錄走到該點須要的最短步數,當遍歷過程當中發現遍歷到了終點,就打印步數,而且退出程序。整段代碼並不複雜,其中最長的next()函數反而是最直觀的。算法
運行結果以下:函數
a1 b2 4