POJ 2488 *** A Knight's Journey

题意:在给定的p*q的棋盘上,问一个骑士是否能够以一个特定的走法从棋盘上的某个位置出发,然后不重复的遍历整个棋盘上的位置。最后的结果要按字典序最小的方式输出。(列用字母表示,行用数字表示,且最后输出是字母在前)。

想法:dfs没什么说的。。但是我却依然不会。。衰。。脑子有点晕。。我写的dfs没用递归,直接写的。。贴代码。。

代码如下:


#pragma warning(disable:4996)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
#include<sstream>
#include<set>
#include<string>
#include<iterator>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

//每个位置可能的行走方式
struct item {
	int a;
	int b;
}mov[8] = { { -2,-1 },{ -2,1 },{ -1,-2 },{ -1,2 },{ 1,-2 },{ 1,2 },{ 2,-1 },{ 2,1 } };

//每个位置的坐标,以及经历了多少种行走方式
struct Elem {
	int x;
	int y;
	int dir;//对应上面的mov数组
};

//记录是否经过某个位置
bool mark[100][100];


int main(void) {
	int time = 0, n, p, q;
	cin >> n;
	while (n--) {
		memset(mark, 0, sizeof(mark));
		cin >> p >> q;
		stack<Elem> ss;//用栈代替递归的功能,将前一个位置的坐标以及最后一次的行走方式压入栈中
		item way[100];//记录路径
		way[1].a = 1, way[1].b = 1;//路径的第一步总是A1
		int signal = 1, flag = 1;//signal记录路径的长度,flag记录是否找到完整的长度为p*q路径
		int x, y, d;//当前的坐标值,与行走方式
		Elem now = { 1,1,0 };
		ss.push(now);
		mark[1][1] = 1;
		while (!ss.empty() && flag) {
			now = ss.top();
			ss.pop();
			x = now.x, y = now.y, d = now.dir;
			while (d < 8 && flag) {
				int m = x + mov[d].a, n = y + mov[d].b;//使用d的行走方式之后到达的(m,n)点
				if (signal == p*q)flag = 0;//判断是否已经遍历所有点
				if (m<=0 || m>q||n<=0 || n>p)++d;//判断(m,n)是否可达
				else if (!mark[m][n]) {//判断(m,n)是否之前已经到达
					mark[m][n] = 1;
					way[++signal].a = m, way[signal].b = n;
					now.x = x, now.y = y, now.dir=d+1;//更新前一个点的数据
					ss.push(now);
					x = m, y = n, d = 0;//更新为当前点
				}
				else ++d;
			}
			//如果已经遍历完所有行走方式都不可以,则压入栈中最后一个元素的位置清零,路径减一
			mark[way[signal].a][way[signal].b] = 0;
			signal--;
		}
		time++;
		cout << "Scenario #" << time << ":" << endl;
		if (flag) 
			cout << "impossible" << endl;
		else {
			for (int i = 1; i <= p*q; ++i)
				cout <<(char)( 'A' + way[i].a - 1) << way[i].b;
			cout << endl;
		}
		cout << endl;
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值