UVa227-Puzzle

题目链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=163

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <cassert>
#define _for(i,a,b) for(int i = (a); i < (b); ++i)
#define _rep(i,a,b) for(int i = (a); i <= (b); ++i)
using namespace std;

struct Point {
	int x, y;
	Point(int x = 0, int y = 0) :x(x), y(y) {}
};

Point operator + (const Point &A, const Point &B) { return Point(A.x + B.x, A.y + B.y); }
Point operator - (const Point &A, const Point &B) { return Point(A.x - B.x, A.y - B.y); }
Point operator * (const Point &A, int p) { return Point(A.x * p, A.y * p); }
Point operator / (const Point &A, int p) { return Point(A.x / p, A.y / p); }
bool operator == (const Point &A, const Point &B) { return (A.x == B.x && A.y == B.y); }
bool operator < (const Point &A, const Point &B) { return A.x < B.x || (A.x == B.x && A.y < B.y); }

const int GSize = 5;
vector<string> grid;
Point ePos;
map<char, Point> DIRS = { { 'A',Point(-1, 0) },{ 'B',Point(1, 0) },{ 'L',Point(0, -1) },{ 'R',Point(0, 1) }, };
bool valid(const Point& p) { return p.x >= 0 && p.x < GSize && p.y >= 0 && p.y < GSize; }

void printGrid() {
	_for(i, 0, GSize) {
		_for(j, 0, GSize) {
			if (j) cout << ' ';
			cout << grid[i][j];
		}
		cout << endl;
	}
}

bool tryMove(char cmd) {
	if (!DIRS.count(cmd)) return false;
	assert(DIRS.count(cmd));
	Point P = ePos + DIRS[cmd];
	if (!valid(P)) return false;
	swap(grid[P.x][P.y], grid[ePos.x][ePos.y]);
	ePos = P;
	return true;
}

int main() {
#ifdef LOCAL
	freopen("Text.txt", "r", stdin);
#endif
	int t = 1;
	string line;
	while (true) {
		grid.clear();
		ePos.x = -1; ePos.y = -1;
		_for(i, 0, GSize) {
			getline(cin, line);
			if (line == "Z") return 0;
			assert(line.size() == GSize);
			_for(j, 0, GSize) {
				if (line[j] != ' ') continue;
				assert(ePos.x == -1 && ePos.y == -1);
				ePos.x = i;
				ePos.y = j;
			}
			grid.push_back(line);
		}
		string moves;
		while (true) {
			getline(cin, line);
			assert(!line.empty());
			bool end = *(line.rbegin()) == '0';
			if (!end) moves.append(line);
			else moves.append(line, 0, line.size() - 1);
			if (end) break;
		}
		bool legal = true;
		for (const auto& m : moves) if (!tryMove(m)) { legal = false; break; }

		if (t > 1) cout << endl;
		cout << "Puzzle #" << t++ << ":" << endl;
		if (legal) printGrid();
		else cout << "This puzzle has no final configuration." << endl;
	}
	return 0;
}

要点:

用map 模拟点的方向;

map<char, Point> DIRS = { { 'A',Point(-1, 0) },{ 'B',Point(1, 0) },{ 'L',Point(0, -1) },{ 'R',Point(0, 1) }, };

使用 std::vector.count(char cmd) 来确定是否存在 字符 cmd,返回1和0,assert()如果 返回0 就直接不执行下列语句。

assert(DIRS.count(cmd));

使用std::string.rbegin() 获取string字符串的第一个字符,

bool end = *(line.rbegin()) == '0';



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值