题解 P1374 【进攻幽暗城】

· · 题解

看别的题解都很欺负新手的没贴完整代码,我来一发完整代码

完完全全的暴力bfs

用队列存三个人每秒的状态,然后每次处理队首元素时直接判断小A是不是死了,或者是不是已经到了魔王的地方了。

注意一点:

这种模拟移动的题目

1.尽量写出每一种的移动状态,然后用数组来存。到时候直接枚举哪一种状态即可。

2.对于固定移动的两个人,也用类似的方法。

这样写的代码较少,可以极大减少出错率。

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#define rel(a) a=readl()
#define r(i,a,b) for(int i=a;i<=b;i++)
#define rr(i,a,b) for(int i=a;i>=b;i--)
#define r2(i,a,b) for(int i=a;i<=b;i+=2)
#define re(a) a=read()
#define pr(a) printf("%d\n",a)
#define in inline
#define ll long long
#define db double
#define id(i,j) ((i-1)*m+j)
using namespace std;
const int N=51;
inline int read(){
    char ch=getchar();
    int w=1,x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
    return x*w;
}
db d;
int n,m,s,mx[9]={0,1,-1,0,0},my[9]={0,0,0,-1,1},Kmx[2][N<<1],Kmy[2][N<<1],x,xx,y,yy,len[2];
struct point{
    int x,y;
    bool o;
}D[N*N];
struct node{
    point K[2],now;
    int out,sum;
};
queue<node>q;
in db dis(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
in void bfs(){
    node fr;fr.K[0]=D[id(x,y)],fr.K[1]=D[id(xx,yy)],fr.now=D[id(x,y)],fr.out=fr.sum=0;
    q.push(fr);
    //q.push((node){D[id(x2,y2)],D[id(x1,y1)],D[id(x1,y1)],0,0});
    while(!q.empty()){
        node fr=q.front();q.pop();
        if(fr.out>s)continue;
        point now=fr.now,Kn[2],nown;int sum=fr.sum,out=fr.out,nx,ny;
        if(now.x==fr.K[1].x&&now.y==fr.K[1].y){
            printf("%d\n",sum);
            exit(0);
        }
        node nstep;
        r(i,0,1){
            nx=fr.K[i].x+Kmx[i][sum%len[i]],ny=fr.K[i].y+Kmy[i][sum%len[i]];
            if(nx<=n&&nx>=1&&ny<=m&&ny>=1&&!D[id(nx,ny)].o)Kn[i]=D[id(nx,ny)];
            else Kn[i]=fr.K[i];
        }
        r(i,0,4){
            nx=now.x+mx[i],ny=now.y+my[i];
            if(nx<=n&&nx>=1&&ny<=m&&ny>=1&&!D[id(nx,ny)].o){
                nown=D[id(nx,ny)];
                r(j,0,1)nstep.K[j]=Kn[j];
                nstep.now=nown;nstep.out=dis(nown,Kn[0])>d?out+1:0; nstep.sum=1+sum;
                q.push(nstep);
            }
        }
    }   
}
int main(){
    re(n),re(m),re(s);scanf("%lf",&d);char ch[N<<1];
    r(i,1,n){
        scanf("%s",ch+1);
        r(j,1,m)D[id(i,j)]=(point){i,j,ch[j]-'0'};
    }
    re(x),re(y),re(xx),re(yy);
    r(i,0,1){
        scanf("%s",ch);len[i]=strlen(ch);int t;
        r(j,0,len[i]-1){
            t=ch[j]-'0';
            if(t==0)Kmx[i][j]=Kmy[i][j]=0;
            else if(t==1)Kmx[i][j]=-1,Kmy[i][j]=0;
            else if(t==2)Kmx[i][j]=1,Kmy[i][j]=0;
            else if(t==3)Kmx[i][j]=0,Kmy[i][j]=-1;
            else if(t==4)Kmx[i][j]=0,Kmy[i][j]=1;
        }
    }
    bfs();
    return 0;
}

/*
3 4 7 3
1010
0000
0101
1 2 3 3
0132401
12131
*/