Sicilly 1152 馬的簡單週遊問題(5*6)

</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;
}


發佈了34 篇原創文章 · 獲贊 25 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章