题意:
一个人掉在一个n*n的洞中,开始位置是(0,0),方向朝右,在这个洞里面有三种东西(1 for Wumpus, 2 for pit and 3 for gold.)这个人每走一步,每转一个方向,爬出坑,捡金子分别都要花掉 ¥10。 求这个人拿到金子和从开始的位置出去的剩钱最多。
分析:
因为涉及到方向和捡金子的状态,需要用四维数组标记,另外,三种转换方向的形式(0左转,1右转,2直行),只有在方向与朝向一直才能向前走。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
//#define LL __int64
#define LL long long
#define pi acos(-1.0)
#define PB push_back()
#define MP make_pair()
#define BG begin()
#define ED end()
#define clr(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define Mod 1e9+7
using namespace std
const int maxn=25
int mp[maxn][maxn]
int vis[maxn][maxn][5][2]
int n
struct node
{
int x,y
int dir
int G
int Mon
bool operator <(const node& h)const{
return Mon<h.Mon
}
}
int dx[4]={-1,1,0,0}
int dy[4]={0,0,-1,1}
bool in(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<n
}
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
}
int bfs(int xx,int yy)
{
if(mp[xx][yy]==2) return -1
clr(vis,0)
node st,ed
priority_queue<node> PQ
st.x=xx
st.y=yy
st.dir=1
st.G=0
st.Mon=0
vis[st.x][st.y][st.dir][st.G]=1
PQ.push(st)
while(!PQ.empty())
{
st=PQ.top()
PQ.pop()
if(st.x==0&&st.y==0&&st.G==1)
return st.Mon-10
for(int i=0
if(i!=2){
ed=st
ed.dir=Change(st.dir,i)
ed.Mon=st.Mon-10
if(vis[st.x][st.y][ed.dir][ed.G]==0){
vis[st.x][st.y][ed.dir][ed.G]=1
PQ.push(ed)
}
continue
}
int zx=st.x+dx[st.dir]
int zy=st.y+dy[st.dir]
if(in(zx,zy)&&vis[zx][zy][st.dir][st.G]==0&&mp[zx][zy]!=1&&mp[zx][zy]!=2){
vis[zx][zy][st.dir][st.G]=1
ed.x=zx
ed.y=zy
ed.Mon=st.Mon-10
ed.dir=st.dir
ed.G=st.G
if(mp[zx][zy]==3) { ed.Mon+=990
PQ.push(ed)
}
}
}
return -1
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin)
#endif // ONLINE_JUDGE
int T
cin>>T
while(T--){
scanf("%d",&n)
int s,xx,yy
clr(mp,0)
while(~scanf("%d%d%d",&s,&xx,&yy)){
if(s==-1&&xx==-1&&yy==-1) break
mp[xx][yy]=s
}
int cnt=0
cnt=bfs(0,0)
cout<<cnt<<endl
}
return 0
}