UVA816 Abbott的复仇 Abbott's Revenge (bfs)

题目传送

bfs找迷宫最短路,不过比传统迷宫问题多了方向,所以加一维就行。
被UVA的输出格式搞崩了心态。。。(默默吐槽一下)

详见代码注释:

#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const char* dir = "NESW";
const char* turn = "FLR";
const int dx[] = { -1,0,1,0 }; //注意本题的横坐标纵坐标与一般直角坐标系的区别
const int dy[] = { 0,1,0,-1 };

int bdir, bx, by, ex, ey;
int step[10][10][4]; //每种状态的步数
bool edg[10][10][4][3]; //是否存在该边

struct node {
	int x, y, dir;
	node(int x = 0, int y = 0, int dir = 0) :x(x), y(y), dir(dir) {}
}last[10][10][4]; //上一步

//方向转换为数字表示
int todir(char c)
{
	return strchr(dir, c) - dir;
}

//转向转换为数字表示
int toturn(char c)
{
	return strchr(turn, c) - turn;
}

//判断是不是表示方向的字母
bool isdir(char c)
{
	return c == 'N' || c == 'E' || c == 'S' || c == 'W';
}

//判断是不是表示转向的字母
bool isturn(char c)
{
	return c == 'F' || c == 'L' || c == 'R';
}

//读入
bool input()
{
	string ss;
	cin >> ss;
	if (ss == "END") return 0;
	cout << ss << endl;//输出第一行字符串
	memset(step, -1, sizeof(step)); //初始化
	memset(edg, 0, sizeof(edg));
	char ch;
	cin >> bx >> by >> ch >> ex >> ey; //读入起点,起始方向,终点
	bdir = todir(ch); //起始方向数字表示
	int tx, ty;
	while (cin >> tx && tx) {
		cin >> ty;
		string s;
		getline(cin, s);
		for (int i = 0; i < s.size(); i++) {
			if (isdir(s[i])) {
				int dir1 = todir(s[i]);
				while (isturn(s[++i])) {
					int turn1 = toturn(s[i]);
					edg[tx][ty][dir1][turn1] = 1; //存在该边
				}
			}
		}
	}
	edg[bx][by][bdir][0] = 1; //起点及起始方向
	return 1;
}

void print_ans(node u)
{
	vector<node> ans;
	while (1) {
		ans.push_back(u);
		if (step[u.x][u.y][u.dir] == 0) break; //到起点退出
		u = last[u.x][u.y][u.dir]; //上一步
	}
	int cnt = 0;
	for (int i = ans.size() - 1; i >= 0; i--) {
		if (cnt % 10 == 0) cout << " ";
		cout << " (" << ans[i].x << "," << ans[i].y << ")";
		if (++cnt % 10 == 0) cout << endl;
	}
	if (ans.size() % 10) cout << endl;
}

node walk(node u, int turn)
{
	int dir = u.dir;
	if (turn == 1) dir = (dir + 3) % 4; //逆时针
	if (turn == 2) dir = (dir + 1) % 4; //顺时针
	return node(u.x + dx[dir], u.y + dy[dir], dir);
}

void solve()
{
	queue<node> q;
	q.push(node(bx, by, bdir)); //起点
	step[bx][by][bdir] = 0;
	while (q.size()) {
		node u = q.front();
		q.pop();
		if (u.x == ex && u.y == ey) {
			print_ans(u);
			return;
		}
		for (int i = 0; i < 3; i++) {
			node v = walk(u, i);
			if (edg[u.x][u.y][u.dir][i] && step[v.x][v.y][v.dir] == -1) {
				step[v.x][v.y][v.dir] = step[u.x][u.y][u.dir] + 1;
				last[v.x][v.y][v.dir] = u;
				q.push(v);
			}
		}
	}
	cout << " No Solution Possible\n"; //无解
}

int main(void)
{
	//freopen("D:\\out.txt", "w", stdout);
	while (input()) {
		solve();
	}
	return 0;
}
发布了30 篇原创文章 · 获赞 50 · 访问量 5294

猜你喜欢

转载自blog.csdn.net/qq_43054573/article/details/104537754