4 5 17 @A.B. a*.*. *..*^ c..b* 4 5 16 @A.B. a*.*. *..*^ c..b*
16 -1
其实这个题目题意并不是很明确,因为第二个图明明可以用20的时间走出出口,但是题目的意识是说不行....那看来这个小伙子有点呆,正好符合俺们bfs无脑的特性.所以我们直接用广搜来解决这个图搜的题目
这里我们先分析第一个问题:
回头路问题,例如:
@A .
a * .
* * .
的问题,首先我们要先去拿钥匙,然后再回头去开门,这里就有了一段重复的路径@.重复走这段路的时候,两次走这里的区别很明显,第一次没有钥匙,但是第二次有钥匙了。区别就在这里,所以我们这里判断是否走过这条路的判断数组vis要弄成三维:
int vis[21][21][1025];//这里第三位的数组为啥那么大呢,一会我们要提及位运算的操作.....这里先卖下关子
现在处理完了回头路问题,这里还有一个难点就是如何判断我们是否有开门的钥匙呢?
这里涉及到一个位运算的东西:(我不是十分会描述位运算的这部分东西,所以下边的这段详解是转载的)http://bluereader.org/article/73263006<-源自.
判断门是否会打开时用 钥匙与门编号进行'&'----> 例如: 1000100010 & 0000100000 = 1 说明可以打开‘A’ + 6这道门。
如果碰到钥匙要加入该钥匙。将钥匙加入钥匙串要进行'|' ---->例如:1000100010 | 0000010000 = 1000110010;’e'入串。
如果我们遇到了钥匙,就要有相对应的加入钥匙的操作:if(a[nex.x][nex.y]>='a'&&a[nex.x][nex.y]<='j') { int temp=a[nex.x][nex.y]-'a'; if((nex.key&(1<<temp))==0)//位运算(如果当前没有这个钥匙) nex.key+=(1<<temp);(入钥) }
if(a[nex.x][nex.y]>='A'&&a[nex.x][nex.y]<='J') { int temp=a[nex.x][nex.y]-'A'; if((nex.key&(1<<temp))==0)//(如果当前没有这个门的钥匙) continue;//(就不能走向这里) }解决了两个最主要的问题,然后贴上完整的代码:
#include<stdio.h> #include<queue> #include<string.h> using namespace std; struct zuobiao { int x,y,key,output; }now,nex; int fx[4]={0,0,1,-1}; int fy[4]={1,-1,0,0}; int vis[21][21][1025]; char a[21][21]; int m,n,time; void bfs(int x,int y) { memset(vis,0,sizeof(vis)); now.x=x; now.y=y; now.output=0; now.key=0; vis[x][y][0]=1; queue<zuobiao >s; s.push(now); while(!s.empty()) { now=s.front(); s.pop(); for(int i=0;i<4;i++) { nex.x=now.x+fx[i]; nex.y=now.y+fy[i]; nex.key=now.key; nex.output=now.output+1; if(nex.x>=0&&nex.x<m&&nex.y>=0&&nex.y<n&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y][nex.key]==0&&nex.output<time) { if(a[nex.x][nex.y]=='^') { printf("%d\n",nex.output); return ; } if(a[nex.x][nex.y]>='a'&&a[nex.x][nex.y]<='j') { int temp=a[nex.x][nex.y]-'a'; if((nex.key&(1<<temp))==0) nex.key+=(1<<temp); } if(a[nex.x][nex.y]>='A'&&a[nex.x][nex.y]<='J') { int temp=a[nex.x][nex.y]-'A'; if((nex.key&(1<<temp))==0) continue; } vis[nex.x][nex.y][nex.key]=1; s.push(nex); } } } printf("-1\n"); return ; } int main() { while(~scanf("%d%d%d",&m,&n,&time)) { int x,y; int ok=0; for(int i=0;i<m;i++) { scanf("%s",a[i]); for(int j=0;j<n;j++) { if(ok==1)break; if(a[i][j]=='@') { x=i; y=j; ok=1; } } } bfs(x,y); } }