2021牛客多校#2 Penguins

原题链接
					https://ac.nowcoder.com/acm/contest/11253/I

题目大意

玩家控制两只企鹅分别在两张 20 × 20 20\times20 20×20的地图上行动。地图上有一些格子是墙壁,无法到达。当控制企鹅向墙壁或者边界移动时,这个操作会被忽略
现在同事控制两只企鹅移动,不过企鹅的移动时镜像的:
⋅ L : 左 边 的 企 鹅 向 左 移 动 , 右 边 的 企 鹅 向 右 移 动 ; ·L:左边的企鹅向左移动,右边的企鹅向右移动; L
⋅ R : 左 边 的 企 鹅 向 右 移 动 , 右 边 的 企 鹅 向 左 移 动 ; ·R:左边的企鹅向右移动,右边的企鹅向左移动; R
⋅ U : 两 只 企 鹅 均 向 上 移 动 ; ·U:两只企鹅均向上移动; U
⋅ D : 两 只 企 鹅 均 向 下 移 动 ; ·D:两只企鹅均向下移动; D
左边企鹅从 ( 20 , 20 ) (20,20) 20,20出发前往 ( 1 , 20 ) (1,20) 1,20,右边的企鹅从 ( 20 , 1 ) (20,1) 20,1出发前往 ( 1 , 1 ) (1,1) 1,1,求最短操作序列。若有多组解,求字典序最小的解。

题解

这题没什么好说的,用 B F S BFS BFS跑一遍模拟就行。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int n=20;
int xx1[]={0,1,0,0,-1};
int xx2[]={0,1,0,0,-1};
int yy1[]={0,0,-1,1,0};
int yy2[]={0,0,1,-1,0};
bool vis[n+1][n+1][n+1][n+1];//记录走过的路径,避免重复走导致超时
char c1[n+1][n+1],c2[n+1][n+1];
char v[5];
struct node{int lx,ly,rx,ry,s,step[4010];};
void print(node k)
{
    node now,next;
    now.lx=20;now.ly=20;now.rx=20;now.ry=1;
    c1[20][20]='A';c2[20][1]='A';
    for(int i=1;i<=k.s;i++)
    {
        next=now;
        int dx1=now.lx+xx1[k.step[i]],dy1=now.ly+yy1[k.step[i]];
        int dx2=now.rx+xx2[k.step[i]],dy2=now.ry+yy2[k.step[i]];
        bool f1=0,f2=0;
        if(dx1<=0||dx1>n||dy1<=0||dy1>n||c1[dx1][dy1]=='#')f1=1;
        if(dx2<=0||dx2>n||dy2<=0||dy2>n||c2[dx2][dy2]=='#')f2=1;
        if(f1==1&&f2==1)continue;
        if(f1==1)next.rx=dx2,next.ry=dy2;
        else if(f2==1)next.lx=dx1,next.ly=dy1;
        else next.rx=dx2,next.ry=dy2,next.lx=dx1,next.ly=dy1;
        c1[next.lx][next.ly]='A';c2[next.rx][next.ry]='A';
        now=next;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)printf("%c",c1[i][j]);
        printf(" ");
        for(int j=1;j<=n;j++)printf("%c",c2[i][j]);
        printf("\n");
    }
}
void bfs()
{
    queue<node> q;
    node now,next;
    now.lx=20;now.ly=20;now.rx=20;now.ry=1;now.s=0;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(now.lx==1&&now.ly==20&&now.rx==1&&now.ry==1)
        {
            printf("%d\n",now.s);
            for(int i=1;i<=now.s;i++)printf("%c",v[now.step[i]]);
            printf("\n");
            print(now);
            return;
        }
        else for(int i=1;i<=4;i++)
        {
            next=now;
            int dx1=now.lx+xx1[i],dy1=now.ly+yy1[i];//左边企鹅的下一步
            int dx2=now.rx+xx2[i],dy2=now.ry+yy2[i];//右边企鹅的下一步
            bool f1=0,f2=0;
            if(dx1<=0||dx1>n||dy1<=0||dy1>n||c1[dx1][dy1]=='#')f1=1;
            if(dx2<=0||dx2>n||dy2<=0||dy2>n||c2[dx2][dy2]=='#')f2=1;
            if(f1==1&&f2==1)continue;//若两只企鹅的下一步均为无效操作,则不执行
            if(f1==1)next.rx=dx2,next.ry=dy2;
            else if(f2==1)next.lx=dx1,next.ly=dy1;
            else next.rx=dx2,next.ry=dy2,next.lx=dx1,next.ly=dy1;
            if(vis[next.lx][next.ly][next.rx][next.ry]==1)continue;
            vis[next.lx][next.ly][next.rx][next.ry]=1;
            next.s=now.s+1;
            next.step[next.s]=i;
            q.push(next);
        }
    }
}
int main()
{
    memset(vis,0,sizeof(vis));
    v[1]='D';v[2]='L';v[3]='R';v[4]='U';
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            cin>>c1[i][j];
        for(int j=1;j<=n;j++)
            cin>>c2[i][j];
    }
    vis[20][20][20][1]=1;
    bfs();
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值