欢迎来到蒟蒻mqd的博客

2020牛客寒假算法基础集训营4 G-街机争霸 广搜

G-街机争霸

https://ac.nowcoder.com/acm/contest/4680/G

题解

​ 一道还算正常的广搜题,对于不断移动僵尸,看看数据范围就明白了,移动范围不超过10, 那我们就可以增加一维时间来记录状态mp[x,y,t]表示在(x,y)坐标,t时刻的状态,因为僵尸只移动k步,所以\(2*k-2\) 步之后地图又完全一样了,所以\(t<20\)。把状态确定好之后就直接搜索板子一套就好了。

感想

​ 好久没打过广搜了,一开始竟然觉得深搜也行,心想状态就那么几种。结果连样例都过不了,于是恍然大悟,深搜可不能保证每个状态加入队列一次,因为可能有更短的时间在之后才搜到,然后改成了广搜。样例过了,但是它一直说超过内存限制,这就很迷了。看了半天不知道拿错了,吃完午饭回来,想反正找不出错,不如看看我是不是入队的元素太多了。理论上不会超过\(5*10^6\), 我就加了在代码中加了一条,\(if (Q.size()>5000000) return 0\) , 结果答案错误,那肯定是入队的元素太多了,但是我每个状态都标记了,这就很奇怪了。又想了一会,才发现我是在出队列才标记,如队列没有标记。那肯定会出现重复入队,然后终于AC了,真是悲催。

代码

#include<bits/stdc++.h>
using namespace std;
#define N 510
#define ll long long
const int INF=1e9+7;
int n,m,mo,ans=INF,sx,sy;
char mp1[N][N];
bool mp2[N][N][20];
bool f[N][N][20];
int lx[4]={0,0,-1,1};
int ly[4]={-1,1,0,0};
bool flag=false;
void readChar(char& c){
    c=getchar();
    while(c!='A' && c!='L' && c!='&' && c!='#') c=getchar();
}
struct Point{int x, y, sum;};
bool dfs(){
    int tot=0;
    if (mp2[sx][sy][0]==1) return 0;
    queue<Point>Q;
    Q.push(Point{sx,sy,0});
    int x,y,t,sum;
    Point u;
    while(!Q.empty()){
        //cout<<Q.size()<<endl;
        u=Q.front(); Q.pop();
        x=u.x; y=u.y; t=u.sum%mo; sum=u.sum;
        f[x][y][t]=1;
        if (mp1[x][y]=='A'){flag=1; ans=min(ans,sum);return 1;}
        t=(t+1)%mo;
        sum++;
        for(int i=0;i<4;i++){
            tot++;
            int xx=lx[i]+x, yy=ly[i]+y;
            if (xx<1 || xx>n || yy<1 || yy>m)continue;
            if (mp2[xx][yy][t]) continue;
            if (mp1[xx][yy]=='&')continue;
            if (f[xx][yy][t])continue;
            f[xx][yy][t]=1;
            Q.push(Point{xx,yy,sum});
        }
    }
    return 0;
}
void work(){
    int num,k;
    cin>>n>>m>>num>>k;
    mo=2*k-2;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            readChar(mp1[i][j]);
            if (mp1[i][j]=='L'){sx=i;sy=j;}
        }
    for(int i=1;i<=num;i++){
        int x,y; string c;
        cin>>x>>y>>c;
        if (c[0]=='U'){
            int t=0;
            for(int j=x;t<=k-1;j--,t++)mp2[j][y][t]=1;
            for(int j=x-k+2;t<2*k-2;j++,t++)mp2[j][y][t]=1;
        }
        if (c[0]=='D'){
            int t=0;
            for(int j=x;t<=k-1;j++,t++)mp2[j][y][t]=1;
            for(int j=x+k-2;t<2*k-2;j--,t++)mp2[j][y][t]=1;
        }
        if (c[0]=='L'){
            int t=0;
            for(int j=y;t<=k-1;j--,t++)mp2[x][j][t]=1;
            for(int j=y-k+2;t<2*k-2;j++,t++)mp2[x][j][t]=1;
        }
        if (c[0]=='R'){
            int t=0;
            for(int j=y;t<=k-1;j++,t++)mp2[x][j][t]=1;
            for(int j=y+k-2;t<2*k-2;j--,t++)mp2[x][j][t]=1;
        }
    }
    bool flag=dfs();
    if (flag)cout<<ans;
    else cout<<"Oh no";
}
int main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    work();
    
}


posted @ 2020-03-01 11:29  mmqqdd  阅读(190)  评论(0编辑  收藏  举报