您的位置:首页 > 其它

【搜索】 HDU 2128 Tempter of the Bone II BFS 状压

2014-09-16 22:56 411 查看
将每次移动用vis数组储存下用于判重

图上数字表示钥匙有多少把。。。不是编号。。。nc了

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 11111
#include <queue>
#include <vector>
#define LL long long
const int INF = 999999;
char mp[13][13];
int mat[11][11];
int n,m;
struct node
{
int x,y,step;
int key;
LL well;
LL bomb;
bool operator < (const node &a) const
{
return step>a.step;//最小值优先
}
};
vector <node>vis[10][10][90*9];
priority_queue<node>q;
bool pd(node c)
{
for(int i=0; i<vis[c.x][c.y][c.key].size(); i++)
{
if(vis[c.x][c.y][c.key][i].well==c.well&&vis[c.x][c.y][c.key][i].bomb==c.bomb)
return false;
}
return true;
}
int xx[4]= {1,0,-1,0};
int yy[4]= {0,1,0,-1};
int welll=0,bom=0;
int bfs(int x,int y)
{
while(!q.empty())
q.pop();
memset(vis,false,sizeof(vis));
node front;
front.x=x,front.y=y;
front.key=front.step=0;
front.well=(1LL<<welll )-1;
front.bomb=0;
q.push(front);
while(!q.empty())
{
front=q.top();
q.pop();
for(int i=0; i<4; i++)
{
node rear=front;
rear.x=front.x+xx[i],rear.y=front.y+yy[i];
rear.step++;
if(rear.x>=0&&rear.y>=0&&rear.x<n&&rear.y<m)
{
if(mp[rear.x][rear.y]=='D')//到终点
{
return rear.step;
}
else if(mp[rear.x][rear.y]=='X'&&(rear.well&1LL<<mat[rear.x][rear.y]))//遇到墙
{
if(rear.key>=1)//身上有炸药
{
rear.key--,rear.step++;
rear.well=rear.well^(1LL<<mat[rear.x][rear.y]);墙被炸
q.push(rear);
vis[rear.x][rear.y][rear.key].push_back(rear);
}
}
else if(mp[rear.x][rear.y]>='1'&&mp[rear.x][rear.y]<='9'&&(rear.bomb&1LL<<mat[rear.x][rear.y])==0)//拿到钥匙
{
rear.key+=mp[rear.x][rear.y]-'0';
rear.bomb=rear.bomb | (1LL<<mat[rear.x][rear.y]);
q.push(rear);
vis[rear.x][rear.y][rear.key].push_back(rear);
}
else
{
if(pd(rear))
{
q.push(rear);
vis[rear.x][rear.y][rear.key].push_back(rear);
}
}
}
}
}
return -1;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m),n+m)
{
node s;
memset(mat,0,sizeof(mat));
memset(mp,0,sizeof(mp));
for(int i=0; i<n; i++)
scanf("%s",mp[i]);
for(int i=0; i<n; i++)         //判重初始化
for(int j=0; j<m; j++)
for(int k=0; k<=(n*m*9); k++)
if(!vis[i][j][k].empty())
vis[i][j][k].clear();
welll=0,bom=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(mp[i][j]=='S')
s.x=i,s.y=j,s.step=0;
else if(mp[i][j]=='X')
{
mat[i][j]=welll++;
}
else if(mp[i][j]>='1'&&mp[i][j]<='9')
{
mat[i][j]=bom++;
}
}
}
printf("%d\n",bfs(s.x,s.y));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: