UVA225

总算A了

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
struct Point
{
	int x, y;
	Point(int x = 0, int y = 0) :x(x), y(y) {}
};
int sum[21];
const int MAXN = 120;                  //最远可到达的地方,其实应该比这个还要小
int dir[4][2] = { { 1,0 },{ 0,1 },{ 0,-1 },{ -1,0 } };
char dict[4] = { 'e','n','s','w' };
bool vis[MAXN * 2][MAXN * 2];
vector<Point> blocks;
vector<char> path;
int n, cnt;
bool isblocked(Point &st, Point &dest)  //判断两点之间是否有障碍物
{
	for (auto &it : blocks) {
		if (it.x == st.x&&it.x == dest.x) {
			if (it.y<min(st.y, dest.y) || it.y>max(st.y, dest.y)) continue;
			else return true;
		}
		if (it.y == st.y&&it.y == dest.y) {
			if (it.x<min(st.x, dest.x) || it.x>max(st.x, dest.x)) continue;
			else return true;
		}
	}
	return false;
}
void dfs(Point pos, int cur)
{
	if (cur > n) {
		if (pos.x == 0 && pos.y == 0) {
			cnt++;
			for (auto it : path) putchar(it);
			puts("");
		}
		return;
	}
	int dist = abs(pos.x) + abs(pos.y);
	if (dist > sum[n] - sum[cur-1]) return; //如果当前需要走的最短距离比还能走的距离都远就剪枝
	Point dest;
	for (int i = 0; i < 4; i++)
	{
		dest.x = pos.x + dir[i][0] * cur, dest.y = pos.y + dir[i][1] * cur;
		if (vis[MAXN + dest.x][MAXN + dest.y]) continue;
		if (!path.empty()) {
			char c = path.back();
			if (c == 'n' && (i == 1 || i == 2)) continue;
			if (c == 's' && (i == 1 || i == 2)) continue;
			if (c == 'w' && (i == 0 || i == 3)) continue;
			if (c == 'e' && (i == 0 || i == 3)) continue;
		}
		if (isblocked(pos, dest)) continue;
		vis[MAXN + dest.x][MAXN + dest.y] = true;
		path.push_back(dict[i]);
		dfs(dest, cur + 1);
		vis[MAXN + dest.x][MAXN + dest.y] = false;
		path.pop_back();
	}
}
void input(int s)
{
	int x, y;
	while (s--)
	{
		scanf("%d%d", &x, &y);
		if (abs(x) >= MAXN - 10 || abs(y) >= MAXN - 10) continue; //一定不可能到达
		vis[MAXN + x][MAXN + y] = true;
		blocks.push_back(Point(x, y));
	}
}
void mark_table()
{
	sum[0] = 0;
	for (int i = 1; i <= 20; i++) sum[i] = sum[i - 1] + i;
}
int main()
{
	mark_table();
	int kcase, s;
	scanf("%d", &kcase);
	while (kcase--)
	{
		Point b(0, 0);
		cnt = 0;
		memset(vis, 0, sizeof(vis));
		blocks.clear();
		path.clear();
		scanf("%d%d", &n, &s);
		input(s);
		dfs(b, 1);
		printf("Found %d golygon(s).\n\n", cnt);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41776911/article/details/82431099