杭电 4771 (BFS)

//一定得注意bfs标记的是状态而不是位置
//用baobao记录宝藏的位置
// 把宝物标号 例如4个宝物是标号为1 2 4 8 则不同的宝物在一起是按位与操作的结果不会相同
//dist[x][y][k]表示经过位置(x,y)时携带的宝物的“二进制按位与操作”结果为k;


#include<stdio.h>
#include<string.h>
#include<queue>


using namespace std;
#define N 600


char map[N][N];
int baobao[N][N];
int n,m,k,xx,yy,an;




struct node
{
int x,y;
int t;
int carry;
};
int dist[N][N][20];
int dir[4][2]={1,0, -1,0, 0,1, 0,-1};


void init()
{
int i,j,x,a,b;
for(i=0;i<n;i++)
{
scanf("%s",map[i]);


}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
if(map[i][j]=='@')
{
xx=i;
yy=j;
}
}
scanf("%d",&k);
memset(baobao,0,sizeof(baobao));
x=1;
an=0;
for(i=1;i<=k;i++)
{
an=an|x;
scanf("%d%d",&a,&b);
a--;
b--;
baobao[a][b]=baobao[a][b]|x;
x=x*2;
}
memset(dist,0,sizeof(dist));

}
int ok(int x,int y)
{
if(x<0||x>=n)
return 0;
if(y<0||y>=m)
return 0;
return 1;
}
int bfs()
{
int i;
queue<node>q;
node cur,next;
cur.x=xx;
cur.y=yy;
cur.t=0;
cur.carry=baobao[xx][yy];
q.push(cur);
dist[xx][yy][cur.carry]=1;
while(!q.empty())
{
cur=q.front();
if(cur.carry==an)
return cur.t;
q.pop();
for(i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
next.t=cur.t+1;
if(ok(next.x,next.y))
{
next.carry=cur.carry|baobao[next.x][next.y];
if(!dist[next.x][next.y][next.carry]&&map[next.x][next.y]!='#')
{
dist[next.x][next.y][next.carry]=1;
q.push(next);
}

}
}
}
return -1;
}
int main ()
{
while(scanf("%d%d",&n,&m),(n+m))
{
init();
int ans=bfs();
printf("%d\n",ans);

}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值