传送门:上海邀请赛E
给定一个n×m的迷宫,给出相邻格子之间的墙或者门的信息,墙说明不可走,假设是门则须要有相应的钥匙才干通过,问是否可以从(1,1)到达(n,m)
一个带状态的bfs,再另记一个状态表示所带钥匙的种类,钥匙种类数最多仅仅有10,因此能够用位来表示钥匙的状态。
/****************************************************** * File Name: 5094.cpp * Author: kojimai * Create Time: 2014年11月03日 星期一 09时24分27秒 ******************************************************/ #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #include<queue> using namespace std; #define FFF 55 bool vis[FFF][FFF][2048]; int map[FFF][FFF],road[FFF][FFF][4]; int move[4][2] ={-1,0,0,1,1,0,0,-1};//0-up 1-right 2-down 3-left struct node { int x,y,t,key; }now,tmp; queue<node> pp; int getg(int g) { if(g == 0) return -1; else return 1 << g; } void solve(int x1,int y1,int x2,int y2,int g) { if(x1 == x2) { if(y1<y2) { road[x1][y1][1] = getg(g); road[x2][y2][3] = getg(g); } else { road[x1][y1][3] = getg(g); road[x2][y2][1] = getg(g); } } else if(x1 < x2) { road[x1][y1][2] = getg(g); road[x2][y2][0] = getg(g); } else { road[x1][y1][0] = getg(g); road[x2][y2][2] = getg(g); } return; } bool judge(int dir) { if(road[now.x][now.y][dir] == -1) return false; if(road[now.x][now.y][dir] == 0) return true; if((road[now.x][now.y][dir] & now.key) == 0) return false; else return true; } void printr() { for(int k = 0;k <= 3;k++) { cout<<" "<<k<<endl; for(int i = 1;i <= 4;i++) { for(int j = 1;j <= 4;j++) { cout<<road[i][j][k]<<' '; } cout<<endl; } } } void printm() { for(int i = 1;i <= 4;i++) { for(int j = 1;j <= 4;j++) { cout<<map[i][j]<<' '; } cout<<endl; } } int main() { int n,m,p,s,x1,x2,y1,y2,g,k,key; while(~scanf("%d",&n)) { while(!pp.empty()) pp.pop(); scanf("%d%d",&m,&p); scanf("%d",&k); memset(map,0,sizeof(map)); memset(road,0,sizeof(road)); while(k--) { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g); solve(x1,y1,x2,y2,g); } scanf("%d",&s); while(s--) { scanf("%d%d%d",&x1,&y1,&key); map[x1][y1] |= (1<<key); } memset(vis,false,sizeof(vis)); int ans = -1; now.x = 1;now.y = 1;now.key = map[1][1];now.t = 0; vis[1][1][now.key] = true; pp.push(now); //printr(); //printm(); while(!pp.empty()) { now = pp.front();pp.pop(); //cout<<" x = "<<now.x<<" y = "<<now.y<<" t = "<<now.t<<" key = "<<now.key<<endl; if(now.x == n&&now.y == m) { ans = now.t; break; } tmp.t = now.t + 1; int xx,yy; for(int i = 0;i < 4;i++) { if(judge(i)) { xx = now.x + move[i][0]; yy = now.y + move[i][1]; if(xx <= 0 || xx > n || yy <= 0 || yy > m) continue; else { tmp.key = now.key | map[xx][yy]; tmp.x = xx; tmp.y = yy; if(!vis[tmp.x][tmp.y][tmp.key]) { vis[tmp.x][tmp.y][tmp.key] = true; pp.push(tmp); } } } } } cout<<ans<<endl; } return 0; }