I-Penguins

这篇博客介绍了一种使用宽度优先搜索(BFS)解决二维空间中两个点间路径问题的方法。博主首先定义了问题的状态空间大小,并指出在边界和障碍物存在的情况下,如何调整移动方向。然后,通过初始化、检查边界和障碍物条件,以及更新状态,实现了BFS算法。最后,博主展示了如何输出路径和验证解决方案的正确性。
摘要由CSDN通过智能技术生成

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

做法:最多可能状态只有20的4次方,即16w,所以直接bfs就行

需要注意的点是:当一边碰到障碍或边界,是不会移动的,所以可能只有一侧移动

#include<bits/stdc++.h>
using namespace std;
bool vis[22][22][22][22];
bool a[25][25];
bool b[25][25];
char c[25][25];
char d[25][25];
 
string ans;
 
struct ZT{
    int x1,y1;
    int x2,y2;
    string road;
};
struct XD{
    int dx;
    int dy;
    string move;
}mv[4];
void init(){
    mv[0].dx=0;
    mv[0].dy=1;
    mv[0].move="R";
 
    mv[1].dx=0;
    mv[1].dy=-1;
    mv[1].move="L";
 
    mv[2].dx=-1;
    mv[2].dy=0;
    mv[2].move="U";
 
    mv[3].dx=1;
    mv[3].dy=0;
    mv[3].move="D";
     
}
bool checkl(int x,int y){
    if(a[x][y])return 0;
    return 1;
}
bool checkr(int x,int y){
    if(b[x][y])return 0;
    return 1;
}
bool bounder(int x,int y){
    if(x>=1&&x<=20&&y>=1&&y<=20)return 1;
    return 0;
}
 
void pro(){
    int x1=20,y1=20,x2=20,y2=1;
    for(int i=0;i<ans.length();i++){
         
        c[x1][y1]='A';
        d[x2][y2]='A';
        if(ans[i]=='L'){
            if(checkl(x1,y1-1)&&bounder(x1,y1-1)){
                y1=y1-1;
            }
            if(checkr(x2,y2+1)&&bounder(x2,y2+1)){
                y2=y2+1;
            }
        }
        if(ans[i]=='R'){
            if(checkl(x1,y1+1)&&bounder(x1,y1+1)){
                y1=y1+1;
            }
            if(checkr(x2,y2-1)&&bounder(x2,y2-1)){
                y2=y2-1;
            }
        }
        if(ans[i]=='U'){
            if(checkl(x1-1,y1)&&bounder(x1-1,y1)){
                x1=x1-1;
            }
            if(checkr(x2-1,y2)&&bounder(x2-1,y2)){
                x2=x2-1;
            }
        }
        if(ans[i]=='D'){
            if(checkl(x1+1,y1)&&bounder(x1+1,y1)){
                x1=x1+1;
            }
            if(checkr(x2+1,y2)&&bounder(x2+1,y2)){
                x2=x2+1;
            }
        }
    }
    c[x1][y1]='A';
    d[x2][y2]='A';
}
 
int main(){
    init();
    string tmp;
     
    for(int i=1;i<=20;i++){
        cin>>tmp;
        for(int j=1;j<=20;j++){
            if(tmp[j-1]=='.') a[i][j]=0;
            else if(tmp[j-1]=='#') a[i][j]=1;
            c[i][j]=tmp[j-1];
        }
        cin>>tmp;
        for(int j=1;j<=20;j++){
            if(tmp[j-1]=='.') b[i][j]=0;
            else if(tmp[j-1]=='#') b[i][j]=1;
            d[i][j]=tmp[j-1];
        }
    }
 
    bool flag=1;
    ZT s;
    s.x1=20,s.y1=20,s.x2=20,s.y2=1,s.road="";
    queue<ZT>q;
    q.push(s);
    vis[20][20][20][1]=1;
    while(flag){
        ZT tmp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int x1,y1,x2,y2;
            x1=tmp.x1+mv[i].dx;
            y1=tmp.y1+mv[i].dy;
            string rd=tmp.road+mv[i].move;
            if(i<2){
                x2=tmp.x2+mv[!i].dx;
                y2=tmp.y2+mv[!i].dy;
            }else{
                x2=tmp.x2+mv[i].dx;
                y2=tmp.y2+mv[i].dy;
            }
            if(!checkl(x1,y1)||!bounder(x1,y1)){
                x1=tmp.x1;
                y1=tmp.y1;
            }
            if(!checkr(x2,y2)||!bounder(x2,y2)){
                x2=tmp.x2;
                y2=tmp.y2;
            }
            if(!vis[x1][y1][x2][y2]){
                vis[x1][y1][x2][y2]=1;
                ZT nzt;
                nzt.x1=x1;
                nzt.x2=x2;
                nzt.y1=y1;
                nzt.y2=y2;
                nzt.road=rd;
                q.push(nzt);
                if(nzt.x1==1&&nzt.x2==1&&nzt.y1==20&&nzt.y2==1){
                    ans=nzt.road;
                    flag=0;
                }
            }
        }
 
    }
 
    cout<<ans.size()<<endl<<ans<<endl;
 
    pro();
 
    for(int i=1;i<=20;i++){
        for(int j=1;j<=20;j++){
            cout<<c[i][j];
        }
        cout<<" ";
        for(int j=1;j<=20;j++){
            cout<<d[i][j];
        }
        cout<<endl;
    }
    //system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值