【搜索】 HDU 2128 Tempter of the Bone II BFS 状压
将每次移动用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; }