题意:刘备从起点走到终点,可以走的路块是'.'或者‘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;
}