2021牛客暑期多校训练营2 I Penguins

题目大意:
给你两个20×20的图
左边图的企鹅要从点(20,20)走到(1,20)
右边图的企鹅要从点(20,1)走到(1,1)
有‘#’的地方不能走
两个企鹅走的时候要同时走并且走的左右方向是相反的
一个企鹅不能走的时候另一个企鹅可以走
走过的路径的符号变成A
让你输出最短的路径长度并且给出走的方案输出最后的图

思路:
emmm就是广搜模拟题
但是一些条件看着还挺烦人的
看了几个人的代码仿写了一下感觉最好的那个
做个记录,以后再回来看看

#include <bits/stdc++.h>
using namespace std;
struct node{
      int x1,y1,x2,y2;
};
queue<node>q;
char a1[30][30];
char a2[30][30];
int d[30][30][30][30];
int dx[]={1,0,0,-1};
int dy[2][4]={0,-1,1,0,0,1,-1,0};
char op[]={'D','L','R','U'};
char p[30][30][30][30];
node pre[30][30][30][30];
char s[1000000];
int ans=0;
void bfs(){
    memset(d,0x3f3f,sizeof(d));
    d[20][20][20][1]=0;
    q.push({20,20,20,1});
    while(!q.empty()){
        node t=q.front();
        int dis=d[t.x1][t.y1][t.x2][t.y2];
        q.pop();
        for(int i=0;i<4;i++){
            int x1=t.x1+dx[i],y1=t.y1+dy[0][i],x2=t.x2+dx[i],y2=t.y2+dy[1][i];
            if(a1[x1][y1]!='.')x1-=dx[i],y1-=dy[0][i];
            if(a2[x2][y2]!='.')x2-=dx[i],y2-=dy[1][i];
            if(dis+1<d[x1][y1][x2][y2]){
            d[x1][y1][x2][y2]=dis+1;
             pre[x1][y1][x2][y2]={t.x1,t.y1,t.x2,t.y2};
             p[x1][y1][x2][y2]=op[i];
             q.push({x1,y1,x2,y2});
            }
        }
    }
    return;
}
void solve(int x1,int y1,int x2,int y2){
         a1[x1][y1]=a2[x2][y2]='A';
         node t=pre[x1][y1][x2][y2];
         if(x1==20&&y1==20&&x2==20&&y2==1)return;
         solve(t.x1,t.y1,t.x2,t.y2);
         s[ans++]=p[x1][y1][x2][y2];
        return;
}
int main()
{
    for(int i=1;i<=20;i++){
        scanf("%s%s",a1[i]+1,a2[i]+1);
    }
    bfs();    solve(1,20,1,1);
    cout<<ans<<endl<<s<<endl;
    for(int i=1;i<=20;i++){
        printf("%s %s\n",a1[i]+1,a2[i]+1);
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值