</pre><h1 style="color:rgb(0,93,169); font-size:12pt; line-height:15pt; text-decoration:underline; font-family:Verdana">Description</h1><p></p><p></p><p style="color:rgb(51,51,51)">在一個5 * 6的棋盤中的某個位置有一隻馬,如果它走29步正好經過除起點外的其他位置各一次,這樣一種走法則稱馬的周遊路線,試設計一個算法,從給定的起點出發,找出它的一條周遊路線。</p><p style="color:rgb(51,51,51)">爲了便於表示一個棋盤,我們按照從上到下,從左到右對棋盤的方格編號,如下所示:</p><p style="color:rgb(51,51,51)">1 2 3 4 5 6</p><p style="color:rgb(51,51,51)">7 8 9 10 11 12</p><p style="color:rgb(51,51,51)">13 14 15 16 17 18</p><p style="color:rgb(51,51,51)">19 20 21 22 23 24</p><p style="color:rgb(51,51,51)">25 26 27 28 29 30</p><span style="color:rgb(51,51,51)">馬的走法是“日”字形路線,例如當馬在位置</span><span style="color:rgb(51,51,51)">15</span><span style="color:rgb(51,51,51)">的時候,它可以到達</span><span style="color:rgb(51,51,51)">2</span><span style="color:rgb(51,51,51)">、</span><span style="color:rgb(51,51,51)">4</span><span style="color:rgb(51,51,51)">、</span><span style="color:rgb(51,51,51)">7</span><span style="color:rgb(51,51,51)">、</span><span style="color:rgb(51,51,51)">11</span><span style="color:rgb(51,51,51)">、</span><span style="color:rgb(51,51,51)">19</span><span style="color:rgb(51,51,51)">、</span><span style="color:rgb(51,51,51)">23</span><span style="color:rgb(51,51,51)">、</span><span style="color:rgb(51,51,51)">26</span><span style="color:rgb(51,51,51)">和</span><span style="color:rgb(51,51,51)">28</span><span style="color:rgb(51,51,51)">。但是規定馬是不能跳出棋盤外的,例如從位置</span><span style="color:rgb(51,51,51)">1</span><span style="color:rgb(51,51,51)">只能到達</span><span style="color:rgb(51,51,51)">9</span><span style="color:rgb(51,51,51)">和</span><span style="color:rgb(51,51,51)">14</span><span style="color:rgb(51,51,51)">。</span><p><span style="color:rgb(51,51,51)"></span></p><p><span style="color:rgb(51,51,51)"></span></p><h1 style="color:rgb(0,93,169); font-size:12pt; line-height:15pt; text-decoration:underline; font-family:Verdana">Input</h1><p></p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:宋體">輸入有若干行。每行一個整數</span><span lang="EN-US" style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:'Times New Roman'">N(1<=N<=30)</span><span style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:宋體">,表示馬的起點。最後一行用</span><span lang="EN-US" style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:'Times New Roman'">-1</span><span style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:宋體">表示結束,不用處理。</span></p><h1 style="color:rgb(0,93,169); font-size:12pt; line-height:15pt; text-decoration:underline; font-family:Verdana">Output</h1><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:宋體">對輸入的每一個起點,求一條周遊線路。對應地輸出一行,有</span><span lang="EN-US" style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:'Times New Roman'">30</span><span style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:宋體">個整數,從起點開始按順序給出馬每次經過的棋盤方格的編號。相鄰的數字用一個空格分開。</span></p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="margin:10px 0px; font-size:10.5pt; line-height:21px; font-family:宋體"></span></p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)">解題思路:</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)">1數據結構:</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> 用結構體 Node 來標記每個節點,</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span> x // 節點橫座標</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span> y // 節點縱座標</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span> z // 節點數字</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span> s // 表示已搜索的可走下一步的節點列表的序號</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> 用 bool array[m][n] 標記對應節點是否訪問過</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> 用 stack<Node> list 存儲訪問列表,利用深搜算法搜索節點。</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)">2 僞代碼:</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> 1)push begin into list</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> 2)while list is not empty </p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span>do <span style="white-space:pre"> </span></p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span>find one node of the next can search;</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span>if(find),push it into list;</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span>else not find, pop the top of the list.</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> end while</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> 3) if(the size of list == 5*6), print the result</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"><span style="white-space:pre"></span>else print the error message.</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"> end.</p><p style="margin-top:10px; margin-bottom:10px; font-size:15px; line-height:22.5px; font-family:Verdana; color:rgb(51,51,51)"></p><pre name="code" class="cpp">#include<iostream>
#include<string.h>
#include<stack>
#define m 5
#define n 6
using namespace std;
struct Node {
int z; // the number of the node
int x; // the x-coordinate
int y; // the y-coordinate
int s; // the number of the next node had search
Node(){
z = 0;
x = 0;
y = 0;
s = 0;
}
Node(int zz) {
z = zz;
x = (z - 1) / 6;
y = z - 6 * x - 1;
s = 0;
}
Node(int xx, int yy) {
x = xx;
y = yy;
z = 6 * x + y + 1;
s = 0;
}
Node findNext(int i) {
int xx;
int yy;
switch(i) {
case 1: xx = x - 2; yy = y - 1; break;
case 2: xx = x - 2; yy = y + 1; break;
case 3: xx = x - 1; yy = y + 2; break;
case 4: xx = x + 1; yy = y + 2; break;
case 5: xx = x + 2; yy = y + 1; break;
case 6: xx = x + 2; yy = y - 1; break;
case 7: xx = x + 1; yy = y - 2; break;
case 8: xx = x - 1; yy = y - 2; break;
default: xx = 0; yy = 0; break;
}
Node node(xx, yy);
return node;
}
bool isValid() {
return x >= 0 && x < m && y >= 0 && y < n;
}
};
int main() {
int N;
while (cin >> N && N != -1) {
Node begin(N);
//the list stored the node had search
stack<Node> list;
//the array to marck the nodes whether had been search
bool arr[m][n];
memset(arr, false, m*n);
list.push(begin);
arr[begin.x][begin.y] = true;
//the algorithm of DSF
while (!list.empty()) {
cout << list.size() << endl;
if (list.size() == m*n) {
break;
}
//the num of the node had search
int i;
for (i = list.top().s+1; i <= 8; i++) {
Node item = list.top().findNext(i);
list.top().s = i;
//if the next node haven't searched, push into the list
if (item.isValid() && !arr[item.x][item.y]) {
list.push(item);
arr[item.x][item.y] = true;
break;
}
}
//if do not find the node, pop the top of the list
if (i > 8) {
arr[list.top().x][list.top().y] = false;
list.pop();
}
}
//succeed
if (list.size() == 30) {
stack<Node> ll;
for (int i = 0; i < 30; i++) {
ll.push(list.top());
list.pop();
}
for (int i = 0; i < 30; i++) {
cout << ll.top().z << " ";
ll.pop();
}
cout << endl;
}
else {
cout << "Not Find!" << endl;
}
}
return 0;
}
Sicilly 1152 馬的簡單週遊問題(5*6)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.