2021牛客多校第二场 I——Penguins

题目大意

给你两个 20 × 20 20 \times 20 20×20 的地图,’#’ 代表不可走,’.‘代表可走。对于第一张图,你需要从右下角走到右上角,对于第二张图你需要从左下角走到左上角。注意,你是同时操控两个小人,他们左右方向相反,上下方向相同,如果走某个方向,有一个人下一步是不可走,那么他会停在原地。问你最少需要多少步两个人都走到终点,如果步数相同,输出操作顺序字典序最小的,最短步数,操作顺序,最后把走的路径上的点标位’A’

解题思路

我们将第二张图反转一下,这样我们方便一点。定义操作顺序 ‘D’, ‘L’, ‘R’, ‘U’,然后进行一个dfs就可以了,注意要记录路径

Code


#include <bits/stdc++.h>
#define ll long long
#define qc ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define fi first
#define se second
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define pb push_back
using namespace std;
const int MAXN = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int xx[4] = {1, 0, 0, -1};
int yy[4] = {0, -1, 1, 0};
int vis[22][22][22][22];
char mp1[22][22], mp2[22][22];
struct node{
	int x1, y1, x2, y2, d, t;
};
node path[22][22][22][22];
char mp[4] = {'D', 'L', 'R', 'U'};
bool check(int x1, int y1, int x2, int y2){
	if(!vis[x1][y1][x2][y2] && mp1[x1][y1] == '.' && mp2[x2][y2] == '.')
		return 1;
	return 0;
}
void solve(){
	for(int i = 1; i <= 20; i++)   {
		scanf("%s%s",mp1[i] + 1, mp2[i] + 1);
		reverse(mp2[i] + 1, mp2[i] + 21);
	}
	for (int i = 1; i <= 20; ++i){
		mp1[i][0] = mp1[i][21] = mp2[i][0] = mp2[i][21] = '#';
		mp1[0][i] = mp1[21][i] = mp2[0][i] = mp2[21][i] = '#';
	}
	queue<node> q;
	q.push(node{20, 20, 20, 20, -1, 0});
	vis[20][20][20][20] = 1;
	path[20][20][20][20] = node{20, 20, 20, 20, -1, 0};
	node anstmp;
	anstmp.t = inf;
	while(!q.empty()){
		node tmp = q.front();
		q.pop();
		// printf("%d %d %d %d\n", tmp.x1, tmp.y1, tmp.x2, tmp.y2);
		if(tmp.x1 == 1 && tmp.y1 == 20 && tmp.x2 == 1 && tmp.y2 == 20){
			vector<char> ans;
			node temp = tmp;
			while(temp.d != -1){
				ans.pb(mp[temp.d]);
				mp1[temp.x1][temp.y1] = 'A';
				mp2[temp.x2][temp.y2] = 'A';
				temp = path[temp.x1][temp.y1][temp.x2][temp.y2];
			}
			mp1[20][20] = mp2[20][20] = 'A';
			printf("%d\n", (int)ans.size());
			reverse(ans.begin(), ans.end());
			for(auto it : ans)
				putchar(it);
			printf("\n");
			for(int i = 1; i <= 20; i++){
				mp1[i][21] = mp2[i][21] = 0;
				reverse(mp2[i] + 1, mp2[i] + 21);
				printf("%s %s\n",mp1[i] + 1, mp2[i] + 1);
			}
			return ;
		}
		for(int i = 0; i < 4; i++){
			int dx1 = tmp.x1 + xx[i];
			int dy1 = tmp.y1 + yy[i];
			int dx2 = tmp.x2 + xx[i];
			int dy2 = tmp.y2 + yy[i];
			if(check(dx1, dy1, dx2, dy2)){
				vis[dx1][dy1][dx2][dy2] = 1;
				q.push(node{dx1, dy1, dx2, dy2, i, tmp.t + 1});
				path[dx1][dy1][dx2][dy2] = tmp;
			}
			if(check(dx1, dy1, tmp.x2, tmp.y2) && mp2[dx2][dy2] == '#'){
				vis[dx1][dy1][tmp.x2][tmp.y2] = 1;
				q.push(node{dx1, dy1, tmp.x2, tmp.y2, i, tmp.t + 1});
				path[dx1][dy1][tmp.x2][tmp.y2] = tmp;
			}
			if(check(tmp.x1, tmp.y1, dx2, dy2) && mp1[dx1][dy1] == '#'){
				vis[tmp.x1][tmp.y1][dx2][dy2] = 1;
				q.push(node{tmp.x1, tmp.y1, dx2, dy2, i, tmp.t + 1});
				path[tmp.x1][tmp.y1][dx2][dy2] = tmp;
			}
		}
	}

}

int main()
{
    #ifdef ONLINE_JUDGE
    #else
       freopen("in.txt", "r", stdin);
       freopen("out.txt", "w", stdout);
    #endif

    // qc;
    int T;
    // cin >> T;
    T = 1;
    while(T--){

        solve();
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值