题目链接:ZOJ 3890 Wumpus
题意:一个人在n*n的地图的左下角,他想逃出地图,并且他想要分数达到最高,他可以做的操作有直走,左转,右转,射击,爬,挖金矿6个操作,每个操作后分数减10,但是挖到金矿分数加1000,问你逃出地图的最大分数是多少。他可能遇到怪兽但是他不射击(也就是说没有射击的操作),金库在地图中也只有一个。
思路:BFS搜一遍就好了
AC代码:
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
int mp[25][25];
int xx[4]={-1,1,0,0};
int yy[4]={0,0,-1,1};//0shang 1xia 2zuo 3you
int vis[25][25][10][2];
int n;
struct node {
int x,y;
int s,g;
int dir;//面对的方向
bool operator<(const node &hh)const {
return s<hh.s;
}
}front,rear;
bool judge(int x,int y){
if(x>=0 && y>=0 && x<n && y<n)
return true;
return false;
}
int Change(int dir,int ch){
if(dir==0 && ch==0) return 2;
if(dir==0 && ch==1) return 3;
if(dir==1 && ch==0) return 3;
if(dir==1 && ch==1) return 2;
if(dir==2 && ch==0) return 1;
if(dir==2 && ch==1) return 0;
if(dir==3 && ch==0) return 0;
if(dir==3 && ch==1) return 1;
}
//0左转,1右转,2直行
//0shang 1xia 2zuo 3you
int bfs(){
node sta;
int dx,dy,i;
memset(vis,0,sizeof vis);
if(mp[0][0]==2)
return -1;
priority_queue<node> q;
sta.x=0,sta.y=0,sta.s=0,sta.g=0,sta.dir=1;
vis[sta.x][sta.y][sta.dir][0]=1;
q.push(sta);
while(!q.empty()){
front=q.top();
q.pop();
for(i=0;i<3;i++){
if(i!=2){
rear=front;
rear.dir=Change(front.dir,i);
rear.s=front.s-10;
if(vis[rear.x][rear.y][rear.dir][rear.g]==0){
vis[rear.x][rear.y][rear.dir][rear.g]=1;
q.push(rear);
}
continue;
}
dx=front.x+xx[front.dir];
dy=front.y+yy[front.dir];
if(!judge(dx,dy))
continue;
if(dx==0 && dy==0 && front.g==1){
return front.s-20;
}
if(vis[dx][dy][front.dir][front.g]==0 && mp[dx][dy]!=1 && mp[dx][dy]!=2) {
vis[dx][dy][front.dir][front.g]=1;
rear.x=dx;
rear.y=dy;
rear.s=front.s-10;
rear.dir=front.dir;
if(mp[dx][dy]==3) {
rear.s=rear.s+990;
rear.g=1;
}
q.push(rear);
}
}
}
return -1;//走不出去也是-1
}
int main(){
int t;
int op,x,y;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(mp,0,sizeof mp);
while(1){
scanf("%d %d %d",&op,&x,&y);
if(op==-1 && x==-1 && y==-1)
break;
mp[x][y]=op;
}
int ans=bfs();
printf("%d\n",ans);
}
return 0;
}
/*
2
3
1 1 1
2 2 0
3 2 2
2 0 0
-1 -1 -1
1
-1 -1 -1
*/