codevs 1026 逃跑的拉尔夫

去题面的传送门

BFS
状态多一维表示目前处理到第几个方向

一开始的打法wa掉了。换了一种打法过了。
后来一想,之前的打法到底哪里错了!?
于是开始对拍。
拍出一组数据
发现很诡异的情况
在判断下一个格子是否可以走的时候,一开始是这样写的:
if(x>=1&&x<=R&&y>=1&&y<=C&&ditu[x][y]==’.’) return true;
有一个点明明是符合的,他却偏偏返回了false
我把各种写法试了一遍之后,发现如果把四个条件分开写,是对的。如果把最后一个条件改为:ditu[x][y]!=’X’,也是对的。讲真真的没有看出来有什么区别。但是不知道为什么这样就是wa。我以为是括号的问题,结果加了括号也是wa。
我现在还是懵逼的。
以后要是知道了为什么不对,再回来说吧

这是改掉之后A了的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn=1000+10;
int N,R,C,dx,dy;
int e[maxn];
char ditu[52][52];
bool vis[52][52][maxn];
struct lxt
{
    int x,y,dir;
};
queue<lxt>q;

bool judge(int x,int y)
{
//  if(x>=1&&x<=R&&y>=1&&y<=C&&(ditu[x][y]=='.')) return true;
    if(x>=1&&x<=R&&y>=1&&y<=C&&ditu[x][y]!='X') return true;
    return false;
}
void bfs()
{
    q.push((lxt){dx,dy,1});
    vis[dx][dy][1]=true;
    while(!q.empty())
    {
        int ux=q.front().x,uy=q.front().y,ud=q.front().dir;
        q.pop();
        int vx=ux,vy=uy,vd=ud;
        if(e[ud]==1) vx--;
        else if(e[ud]==2) vx++;
        else if(e[ud]==3) vy--;
        else vy++;
        if(judge(vx,vy))
        {
            if(ud==N) ditu[vx][vy]='*';
            if(!vis[vx][vy][vd])
            {
                vis[vx][vy][vd]=true;
                q.push((lxt){vx,vy,vd});
            }

        }
        if(vd<N)
        {
            vd++;
            if(judge(vx,vy)&&!vis[vx][vy][vd])
            {
                vis[vx][vy][vd]=true;
                q.push((lxt){vx,vy,vd});
            }
        }

    }
}
int main()
{
    scanf("%d%d",&R,&C);
    for(int i=1;i<=R;++i)
      for(int j=1;j<=C;++j)
      {
        cin>>ditu[i][j];
        if(ditu[i][j]=='*')
        {
            ditu[i][j]='.';
            dx=i;
            dy=j;
        }
      }
    scanf("%d",&N);
    for(int i=1;i<=N;++i)
    {
        string s;
        cin>>s;
        if(s=="NORTH") e[i]=1;
        else if(s=="SOUTH") e[i]=2;
        else if(s=="WEST") e[i]=3;
        else e[i]=4;
    }
    bfs();
    for(int i=1;i<=R;++i)
    {
        for(int j=1;j<=C;++j)
          printf("%c",ditu[i][j]);
        printf("\n");
    }
    return 0;
} 

这是另一种打法:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn=1000+10;
int N,R,C,dx,dy;
int e[maxn];
char ditu[52][52];
bool vis[52][52][maxn];
struct lxt
{
    int x,y,dir;
};
queue<lxt>q;

bool judge(int x,int y)
{
    if(x>=1&&x<=R&&y>=1&&y<=C&&ditu[x][y]=='.') return true;
    return false;
}
void bfs()
{
    q.push((lxt){dx,dy,0});
    vis[dx][dy][0]=true;
    while(!q.empty())
    {
        int ux=q.front().x,uy=q.front().y,ud=q.front().dir;
        q.pop();
        int vx=ux,vy=uy,vd=ud+1;
        while(vd<=N)
        {
            if(e[vd]==1) vx--;
            else if(e[vd]==2) vx++;
            else if(e[vd]==3) vy--;
            else vy++;
            if(judge(vx,vy)&&!vis[vx][vy][vd])
            {
                q.push((lxt){vx,vy,vd});
                vis[vx][vy][vd]=true;
            }
            else break;
        }

    }
}
int main()
{
    scanf("%d%d",&R,&C);
    for(int i=1;i<=R;++i)
      for(int j=1;j<=C;++j)
      {
        cin>>ditu[i][j];
        if(ditu[i][j]=='*')
        {
            ditu[i][j]='.';
            dx=i;
            dy=j;
        }
      }
    scanf("%d",&N);
    for(int i=1;i<=N;++i)
    {
        string s;
        cin>>s;
        if(s=="NORTH") e[i]=1;
        else if(s=="SOUTH") e[i]=2;
        else if(s=="WEST") e[i]=3;
        else e[i]=4;
    }
    bfs();
    for(int i=1;i<=R;++i)
    {
        for(int j=1;j<=C;++j)
        {
            if(vis[i][j][N]) cout<<'*';
            else printf("%c",ditu[i][j]);
        }
        printf("\n");
    }
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值