hdu 4771好题

来源:互联网 发布:原单厂家直拿wsj淘宝 编辑:程序博客网 时间:2024/04/30 18:21
#include<stdio.h>
#include<string.h>//通过只记录每一步此时点的状态。题非常好
#include<queue>
using namespace std;
#define N 110
int map[N][N][30];//一共最多16种状态,记录状态和此时已得到宝物的多少
char ma[N][N];//读入
struct node {
int x,y,t,h;
};
int chu[N][N];//记录刚开始宝物每个点的宝物的数量
int n,m,total;//total表示得到所有宝物时的状态
int dis[4][2]={1,0,-1,0,0,1,0,-1};//四个方向
int judge(node start) {//判断是否越界
if(start.x<1||start.x>n||start.y<1||start.y>m)
return 0;
return 1;
}
int bfs(node start) {
int i;
queue<node>q;
node cur,next;
memset(map,0,sizeof(map));
start.h=chu[start.x][start.y];
start.t=0;
q.push(start);
map[start.x][start.y][start.h]=1;//初始化
while(!q.empty()) {
cur=q.front ();
if(cur.h==total) 
return cur.t;
q.pop ();
for(i=0;i<4;i++) {
next.x=cur.x+dis[i][0];
next.y=cur.y+dis[i][1];
next.t=cur.t+1;
if(judge(next)) {
next.h=cur.h|chu[next.x][next.y];
if(map[next.x][next.y][next.h]==0&&ma[next.x][next.y]!='#') {//记录不是墙时的状态
map[next.x][next.y][next.h]=1;//这个状态已走过
q.push (next);
}
}
}
}
return -1;
}
int main(){
int i,j,r,a,b,k;
while(scanf("%d%d",&n,&m),n||m) {
for(i=1;i<=n;i++)
scanf("%s",ma[i]+1);
node start;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(ma[i][j]=='@') {//找起始点
start.x=i;
start.y=j;
}
scanf("%d",&k);
memset(chu,0,sizeof(chu));
r=1; total=0;
for(i=1;i<=k;i++) {
total=total|r;
scanf("%d%d",&a,&b);
chu[a][b]=r;
r*=2;
}
  printf("%d\n",bfs(start));
}
return 0;
}