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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值