uva 225(dfs)

题意:有一个城市,一个人从城市的(0,0)出发,可以走东南西北四个方向,然后规定第一个方向走1步,左转或右转换个方向走2步,继续换方向走3步。。。,但是城市中会有一些障碍物是不能通过的,给出障碍物坐标,问走n步后是否能返回起点(0,0),如果可以输出每次走的方向,把所有可能情况全部输出。

题解:首先坐标可能出现负数,所以可以把图扩大,估算所走路径不会超过250,所以中点设为(115,115),找到转向规律,直接dfs,跑出答案发现只有走的步数是7 8 15 16时才有答案,特判其他答案是0节省时间。

#include <stdio.h>
#include <math.h>
#include <string.h>
const int N = 55;
int len, n, g[255][255], res, path[300];
int flag[4][2] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};
char face[4] = {'e', 'n', 's' ,'w'};

bool judge(int x, int y, int cnt, int f) {
	int xx = x, yy = y;
	for (int i = 1; i <= cnt; i++) {
		xx += flag[f][0];
		yy += flag[f][1];
		if (g[xx][yy] == -1)
			return true;
	}
	return false;
}

void dfs(int x, int y, int cnt, int f) {
	if (cnt > len && x == 115 && y == 115) {
		for (int i = 1; i <= len; i++)
			printf("%c", face[path[i]]);
		printf("\n");
		res++;
		return;
	}
	if (cnt > len)
		return;
	for (int i = 0; i < 4; i++) {
		if (f == -1 || f != i && f + i != 3) {//同方向和180度的跳过
			int dx = x + flag[i][0] * cnt;
			int dy = y + flag[i][1] * cnt;
			if (g[dx][dy] == -1 || g[dx][dy])
				continue;
			if (judge(x, y, cnt, i))
				continue;			
			g[dx][dy] = 1;
			path[cnt] = i;
			dfs(dx, dy, cnt + 1, i);
			g[dx][dy] = 0;
		}
	}
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		memset(g, 0, sizeof(g));
		res = 0;
		scanf("%d%d", &len, &n);
		int a, b;
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &a, &b);
			if (a + 115 > 250 || b + 115 > 250 || a + 115 < 0 || b + 115 < 0)
				continue;
			g[a + 115][b + 115] = -1;
		}
		if (len == 7 || len == 8 || len == 15 || len == 16) {
			dfs(115, 115, 1, -1);
			printf("Found %d golygon(s).\n\n", res);
		}
		else
			printf("Found 0 golygon(s).\n\n");
	}	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值