HDU 3442 优先队列+BFS

来源:互联网 发布:西门子plc伺服编程 编辑:程序博客网 时间:2024/04/30 01:25

点击打开链接

题意:刘备从起点走到终点,可以走的路块是'.'或者‘C'和起点和终点,然后给了A到E,代表了5种伤害,然后对于每种伤害只能对人造成伤害一次,解释一下样例应该就行了,刘备先向下走一次,受到A的一点伤害和B的两点伤害还有C的3点伤害,然后继续向下,虽然也在A和B的攻击范围,但是我已经受过它们的伤害所以不会再次受伤害,一样C已经对刘备造成过伤害,所以不再添加伤害,答案6

思路:挺简单的一道搜索题目,状态压缩学的不好,但是山人自有妙计,我开了7维的数组,每个伤害的状态只能是0或者1,走过便标记一下,剩下的就是简单的bfs了,然后就是找当前点可能收到的伤害,一共就5种,跑一遍找出来即可,我用vector把所有的伤害点全部记录下来找的,应该可以更简单一点,不多说了

#include <math.h>#include <queue>#include <vector>#include <stdio.h>#include <iostream>#include <string.h>#include <stdlib.h>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=60;int sx,sy,ex,ey,n,m;int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int vis[maxn][maxn][2][2][2][2][2];char str[maxn][maxn];struct edge1{    int x,y;    edge1(int a,int b){x=a;y=b;}};vector<edge1>G[10];struct edge{    int x,y,step,flag,flag1,flag2,flag3,flag4;    friend bool operator< (edge n1,edge n2)    {return n1.step>n2.step;}};bool judge(int id,int x,int y){    int dis;    if(id==1) dis=2;    if(id==2) dis=3;    if(id==3) dis=2;    if(id==4) dis=1;    for(unsigned int i=0;i<G[id].size();i++){        edge1 e=G[id][i];        if(abs(e.x-x)+abs(e.y-y)<=dis) return 1;    }    return 0;}int bfs(){    priority_queue<edge>que;    edge c,ne;    memset(vis,0,sizeof(vis));    str[sx][sy]='.';str[ex][ey]='.';    c.x=sx,c.y=sy,c.step=0,c.flag=0,c.flag1=0,c.flag2=0,c.flag3=0,c.flag4=0;    vis[c.x][c.y][0][0][0][0][0]=1;    que.push(c);    while(!que.empty()){        c=que.top();que.pop();        if(c.x==ex&&c.y==ey) return c.step;        for(int i=0;i<4;i++){            int xx=c.x+dir[i][0];            int yy=c.y+dir[i][1];            if(xx<0||xx>n-1||yy<0||yy>m-1||str[xx][yy]=='#') continue;            if(str[xx][yy]!='.'&&str[xx][yy]!='C') continue;            if(vis[xx][yy][c.flag][c.flag1][c.flag2][c.flag3][c.flag4]) continue;            ne.x=xx;ne.y=yy;ne.step=c.step;ne.flag=c.flag;ne.flag1=c.flag1;ne.flag2=c.flag2;ne.flag3=c.flag3;ne.flag4=c.flag4;            if(str[xx][yy]=='C'){                if(ne.flag2==0){ne.flag2=1;ne.step+=3;}            }            if(ne.flag==0&&judge(1,xx,yy)){ne.flag=1;ne.step+=1;}            if(ne.flag1==0&&judge(2,xx,yy)){ne.flag1=1;ne.step+=2;}            if(ne.flag3==0&&judge(3,xx,yy)){ne.flag3=1;ne.step+=4;}            if(ne.flag4==0&&judge(4,xx,yy)){ne.flag4=1;ne.step+=5;}            vis[ne.x][ne.y][ne.flag][ne.flag1][ne.flag2][ne.flag3][ne.flag4]=1;            que.push(ne);        }    }    return -1;}int main(){    int T,cas=1;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        for(int i=0;i<10;i++) G[i].clear();        for(int i=0;i<n;i++) scanf("%s",str[i]);        for(int i=0;i<n;i++){            for(int j=0;j<m;j++){                if(str[i][j]=='$')sx=i,sy=j;                if(str[i][j]=='!')ex=i,ey=j;                if(str[i][j]=='A') G[1].push_back(edge1(i,j));                if(str[i][j]=='B') G[2].push_back(edge1(i,j));                if(str[i][j]=='D') G[3].push_back(edge1(i,j));                if(str[i][j]=='E') G[4].push_back(edge1(i,j));            }        }        int ans=bfs();        printf("Case %d: %d\n",cas++,ans);    }    return 0;}

1 0
原创粉丝点击