题目: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);
}
}
转载地址:http://blog.csdn.net/yuhailin060/article/details/5482998
转载:
学习位压缩很好的一道题,因为只有10把钥匙,那么可以把10钥匙压缩二进制,比如1000就表示身上只要第4把钥匙的状态,110表示带有第2把和第3把钥匙,那么要判断当前的钥匙串有没有能打开当前门钥匙,那么就只要一个&运算就可以,因为11101110&00100000==00100000 这样就说明那一把钥匙在里面,若为0就不在这里面。如果对于当前点是一把钥匙的时候,只要|运算就可以了,11101110 | 00010000 z这样就把当前这把钥匙放进了钥匙串里面了