LL
做法:因为钥匙最多有10把,2^10 =1024,所以可以把10把钥匙有没有的情况记录在 一个数中。 num的第三维就是 钥匙 拥有的状态。然后就和普通的bfs一样了。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <map> using namespace std; int n,m,t; char mp[22][22]; int num[22][22][1050];//位置 钥匙状态 int dir[4][2]={-1,0,1,0,0,1,0,-1}; int ex,ey; int stax,stay; struct point { int x,y,step,key; }; int ok(int x,int y) { if(!(x>=0&&x<n&&y>=0&&y<m)) return 0; char ch=mp[x][y]; if(ch<='J'&&ch>='A') return 3; //门 if(ch<='j'&&ch>='a') return 2; //key if(ch!='*') return 1; return 0; } int bfs() { if(t==0) return -1; point sta,now,tem; sta.x=stax; sta.y=stay; sta.step=0; sta.key=0; queue<point> q; q.push(sta); while(!q.empty()) { now=q.front(); q.pop(); if(now.step!=0&&now.step%t==0) { return -1; //now.x=stax; //now.y=stay; } if(now.x==ex&&now.y==ey) return now.step; for(int i=0;i<4;i++) { int xx=now.x+dir[i][0]; int yy=now.y+dir[i][1]; int cdt=ok(xx,yy);//condition int key=now.key; if(cdt==0) continue; if(cdt==3&&(key&(1<<(mp[xx][yy]-'A')))==0) continue; if(cdt==2) key|=(1<<(mp[xx][yy]-'a')); if(num[xx][yy][key]==-1||num[xx][yy][key]>now.step+1) { tem.x=xx; tem.y=yy; tem.step=now.step+1; tem.key=key; num[xx][yy][key]=now.step+1; q.push(tem); } } } return -1; } int main() { while(scanf("%d%d%d",&n,&m,&t)!=EOF) { memset(num,-1,sizeof num); for(int i=0;i<n;i++) scanf("%s",mp[i]); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(mp[i][j]=='@') stax=i,stay=j; if(mp[i][j]=='^') ex=i,ey=j; } } printf("%d\n",bfs()); } return 0; }
原文地址:http://blog.csdn.net/u013532224/article/details/44087063