题目:http://acm.hdu.edu.cn/showproblem.php?pid=1429
代码:
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> using namespace std; struct node { int x,y; int step,temp; } ui,op; int fx[4]= {1,0,-1,0}; int fy[4]= {0,1,0,-1}; char maps[25][25]; int n,m,t; int book[25][25][1<<11]; int startx,starty; void bfs(int x,int y) { memset(book,0,sizeof(book)); queue<node>q; ui.x=x; ui.y=y; ui.step=ui.temp=0; book[x][y][0]=1; q.push(ui); while(!q.empty()) { ui=q.front(); q.pop(); if(maps[ui.x][ui.y]=='^'&&ui.step<t) { printf("%d\n",ui.step); return; } for(int i=0; i<4; i++) { op.x=ui.x+fx[i]; op.y=ui.y+fy[i]; op.temp=ui.temp; if(op.x>=0&&op.x<n&&op.y>=0&&op.y<m&&maps[op.x][op.y]!='*') { if(islower(maps[op.x][op.y])) //小写 { int key =(1<<(maps[op.x][op.y] - 'a')) ; op.temp = (op.temp|key) ; if(!book[op.x][op.y][op.temp]) { book[op.x][op.y][op.temp] = 1 ; op.step=ui.step+1; q.push(op); } } else if(isupper(maps[op.x][op.y])) //大写 { int key = (maps[op.x][op.y] - 'A') ; // (next.key&key) ?= key if((op.temp&((1<<key)))&&!book[op.x][op.y][op.temp]) { book[op.x][op.y][op.temp] = 1 ; op.step=ui.step+1; q.push(op) ; } } else { if(book[op.x][op.y][op.temp]==0) { book[op.x][op.y][op.temp]=1; op.step=ui.step+1; q.push(op); } } } } } printf("-1\n"); } int main() { while(~scanf("%d%d%d",&n,&m,&t)) { memset(maps,0,sizeof(maps)); for(int i=0; i<n; i++) { scanf("%s",&maps[i]); for(int j=0; j<m; j++) { if(maps[i][j]=='@') { startx=i; starty=j; } } } bfs(startx,starty); } }
转载:
学习位压缩很好的一道题,因为只有10把钥匙,那么可以把10钥匙压缩二进制,比如1000就表示身上只要第4把钥匙的状态,110表示带有第2把和第3把钥匙,那么要判断当前的钥匙串有没有能打开当前门钥匙,那么就只要一个&运算就可以,因为11101110&00100000==00100000 这样就说明那一把钥匙在里面,若为0就不在这里面。如果对于当前点是一把钥匙的时候,只要|运算就可以了,11101110 | 00010000 z这样就把当前这把钥匙放进了钥匙串里面了