Codeforces 811D Vladik and Favorite Game[模拟][bfs]

题意:说有四个按钮 L,R可能是反的,U,D可能是反的,然后对于你每次输出的(L,R,U,D),会返回一个坐标,到达给定的F 的位置停止。


分析:关键就是判断L,R 是否是反的,U,D 是否是反的,刚开始的位置是(1,1),贴墙的,为了防止走到 * 上,我们可以找一个右边是空的位置,然后输出一个L,如果在原地,那么说明 不反,如果到了右边,说明反了,对于U,D 也同样,知道反没反之后就是当前位置到目标位置的bfs了,将路径存下来,按照是否相反进行输出。


以下是代码:

char mp[105][105];
bool vis[105][105];
pii pre[105][105];
int n, m, x, y;
int tomove[4][2] = { { 0,-1 },{ 0,1 },{ -1,0 },{ 1,0 } };
bool judge(int x, int y) {
	if (x<1 || x>n || y<1 || y>m || vis[x][y] || mp[x][y] == '*')return false;
	else return true;
}
void bfs(int posx, int posy) {
	queue<pii>qe;
	qe.push(pii(posx, posy));
	vis[posx][posy] = 1;
	while (!qe.empty())
	{
		pii now = qe.front(); qe.pop();
		if (now.first == x && now.second == y) break;
		for (int i = 0; i < 4; ++i) {
			int fx = now.first + tomove[i][0], fy = now.second + tomove[i][1];
			if (judge(fx, fy)) {
				pre[fx][fy] = now;
				vis[fx][fy] = 1;
				qe.push(pii(fx, fy));
			}
		}
	}
}

int main() {
	memset(vis, 0, sizeof(vis));
	bool f1 = 0, f2 = 0;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		getchar();
		for (int j = 1; j <= m; ++j) {
			scanf("%c", &mp[i][j]);
			if (mp[i][j] == 'F')x = i, y = j;
		}
	}
	if (x == 1 && y == 1) {
		return 0;
	}
	int px = 1, py = 1, a, b;
	if (mp[px][py + 1] == '.') {
		printf("L\n");
		cin >> a >> b;
		if (mp[a][b] == 'F')return 0;
		if (a == px && b == py)f1 = 0;
		else f1 = 1;
		if (f1) {
			printf("R\n");
			cin >> a >> b;
		}
		px = a, py = b;
		if (mp[px][py] == 'F')return 0;
		while (mp[px + 1][py] == '*') {
			if (f1) {
				printf("L\n");
				cin >> a >> b;
				px = a, py = b;
			}
			else {
				printf("R\n");
				cin >> a >> b;
				px = a, py = b;
			}
			if (mp[px][py] == 'F')return 0;
		}
		printf("U\n");
		cin >> a >> b;
		if (a == px && b == py)f2 = 0;
		else f2 = 1;
		if (mp[px][py] == 'F')return 0;
		if (f2) {
			printf("D\n");
			cin >> a >> b;
			px = a, py = b;
		}
	}
	else
	{
		printf("U\n");
		cin >> a >> b;
		if (mp[a][b] == 'F')return 0;
		if (a == px && b == py)f2 = 0;
		else f2 = 1;
		if (f2) {
			printf("D\n");
			cin >> a >> b;
		}
		px = a, py = b;
		if (mp[px][py] == 'F')return 0;
		while (mp[px][py + 1] == '*') {
			if (f2) {
				printf("U\n");
				cin >> a >> b;
				px = a, py = b;
			}
			else {
				printf("D\n");
				cin >> a >> b;
				px = a, py = b;
			}
			if (mp[px][py] == 'F')return 0;
		}
		printf("L\n");
		cin >> a >> b;
		if (a == px && b == py)f1 = 0;
		else f1 = 1;
		if (mp[px][py] == 'F')return 0;
		if (f1) {
			printf("R\n");
			cin >> a >> b;
			px = a, py = b;
		}
	}
	bfs(px, py);
	int nowx = x, nowy = y;
	stack<char>st;
	while (nowx != px || nowy != py) {
		for (int i = 0; i < 4; ++i) {
			if (pre[nowx][nowy].first + tomove[i][0] == nowx
				&& pre[nowx][nowy].second + tomove[i][1] == nowy) {
				int tmpx = pre[nowx][nowy].first, tmpy = pre[nowx][nowy].second;
				nowx = tmpx, nowy = tmpy;
				if (i == 0)st.push('L');
				else if (i == 1)st.push('R');
				else if (i == 2)st.push('U');
				else st.push('D');
				break;
			}
		}
	}
	while (!st.empty()) {
		if (st.top() == 'U') {
			if (f2)printf("D\n");
			else printf("U\n");
		}
		else if (st.top() == 'D') {
			if (f2)printf("U\n");
			else printf("D\n");
		}
		else if (st.top() == 'L') {
			if (f1)printf("R\n");
			else printf("L\n");
		}
		else {
			if (f1)printf("L\n");
			else printf("R\n");
		}
		cin >> a >> b;
		st.pop();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值