第九十九题 UVa225 Golygons

第九十九题了,还是好激动的…

Imagine a country whose cities have all their streets laid out in a regular grid. Now suppose that a
tourist with an obsession for geometry is planning expeditions to several such cities.
Starting each expedition from the central cross-roads of a city, the intersection labelled (0,0), our
mathematical visitor wants to set off north, south, east or west, travel one block, and view the sights
at the intersection (0,1) after going north, (0,-1) after going south, (1,0) after going east or (-1,0) after
going west. Feeling ever more enthused by the regularity of the city, our mathematician would like to
walk a longer segment before stopping next, going two blocks.
What’s more, our visitor doesn’t want to carry on in the same direction as before, nor wishes to
double back, so will make a 90o
turn either left or right. The next segment should be three blocks,
again followed by a right-angle turn, then four, five, and so on with ever-increasing lengths until finally,
at the end of the day, our weary traveller returns to the starting point, (0,0).
The possibly self-intersecting figure described by these geometrical travels is called a golygon.
Unfortunately, our traveller will making these visits in the height of summer when road works
will disrupt the stark regularity of the cities’ grids. At some intersections there will be impassable
obstructions. Luckily, however, the country’s limited budget means there will never be more than 50
road works blocking the streets of any particular city. In an attempt to gain accountability to its
citizens, the city publishes the plans of road works in advance. Our mathematician has obtained a copy
of these plans and will ensure that no golygonal trips get mired in molten tar.
Write a program that constructs all possible golygons for a city.
Input
Since our tourist wants to visit several cities, the input file will begin with a line containing an integer
specifying the number of cities to be visited.
For each city there will follow a line containing a positive integer not greater than 20 indicating the
length of the longest edge of the golygon. That will be the length of the last edge which returns the
traveler to (0,0). Following this on a new line will be an integer from 0 to 50 inclusive which indicates
how many intersections are blocked. Then there will be this many pairs of integers, one pair per line,
each pair indicating the x and y coordinates of one blockage.
Output
For each city in the input, construct all possible golygons. Each golygon must be represented by a
sequence of characters from the set {n,s,e,w} on a line of its own. Following the list of golygons
should be a line indicating how many solutions were found. This line should be formatted as shown in
the example output. A blank line should appear following the output for each city.
Note: See on the right the diagram of the 1st City
Sample Input
2
8
2
-2 0
6 -2
8
2
2 1
-2 0
Sample Output
wsenenws
Found 1 golygon(s).
Found 0 golygon(s).

【题目大意】
平面上有k个障碍点。 从(0,0)点出发,第一次走1个单位,第二次走2个单位,……, 第n次走n个单位,恰好回到(0,0)。 要求只能沿着东南西北方向走,且每次必须转弯90°(不能沿着同一个方向继续走,也不能后退)。 走出的图形可以自交,但不能经过障碍点,如图 7-25所示。每个转折点只能走一次。 输入n、k(1≤n≤20,0≤k≤50)和所有障碍点的坐标,输出所有满足要求的移动序列(用 news表示北、东、西、南),按照字典序从小到大排列,最后输出移动序列的总数。

【题目分析】
就是搜索,注意剪枝和处理负坐标

// 第一次走一步 第二次两部  第三次三步  第四次四步  第五次五步  以此类推 
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define Maxn 250
#define Limit 105// 处理 负 坐标 
using namespace std;
int dir[4][2] = {{1,0},{0,1},{0,-1},{-1,0}};
int step[Maxn],Ans,n,m;
char dirtion[4] = {'e','n','s','w'};
int sum[Maxn],g[Maxn][Maxn];

inline bool Judge(int x,int y,int d,int f) {
	for(int i=1; i<=d; i++) {
		x += dir[f][0];
		y += dir[f][1];
		if(abs(x) > Limit || abs(y) > Limit) return true;
		if(g[x + Limit][y + Limit] == -1) return true;// 对于一次向前走多步的时候真的没有想出更好的判断方法 
	}
	if(abs(x) + abs(y) > sum[n] - sum[d]) return true;
	
	return false;
}

void DFS(int x,int y,int d,int f) {
	if(d > n)  {// d == n + 1 题目要求恰好走n步 
		if(x == 0 && y == 0) {
			for(int i=1; i<=n; i++) printf("%c",dirtion[step[i]]);
			printf("\n"); Ans++;
		}
		return ;
	}
	for(int i=0; i<4; i++) {
		if(i == f || i + f == 3) continue;
		int dx = x + dir[i][0] * d;
		int dy = y + dir[i][1] * d;
		if(Judge(x,y,d,i)) continue;
		if(g[dx + Limit][dy + Limit]) continue;
		g[dx + Limit][dy + Limit] = 1;
		step[d] = i;
		DFS(dx,dy,d + 1,i);
		g[dx + Limit][dy + Limit] = 0;
	}
}

int main(int argc,char* agrv[]) {
	sum[0] = 0;
	for(int i=1; i<=20; i++) sum[i] = sum[i - 1] + i;
	int T; scanf("%d",&T);
	while(T--) {
		scanf("%d%d",&n,&m);
		memset(g,0,sizeof(g));
		Ans = 0;
		int a,b;
		for(int i=0; i<m; i++) {
			scanf("%d%d",&a,&b);
			if(abs(a) > Limit || abs(b) > Limit) continue;
			g[a + Limit][b + Limit] = -1;
		}
		DFS(0,0,1,-1);
		printf("Found %d golygon(s).\n\n",Ans);
	} 
}

猜你喜欢

转载自blog.csdn.net/qq_35776409/article/details/104378635
今日推荐