NEU710(wanghang走迷宫)

题目链接:传送门

题目大意:给你一个图,要从起点走到终点并且要吃够足够的金币才能出去,图上有金币(只能吃一次),

            有传送门(用一次消耗1金币,必须有金币才能使用),问最少需要多少步才能出去。不能出去输出-1

题目思路:搜索+状态压缩技巧

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <cstring>
  7 #include <stack>
  8 #include <cctype>
  9 #include <queue>
 10 #include <string>
 11 #include <vector>
 12 #include <set>
 13 #include <map>
 14 #include <climits>
 15 #define lson root<<1,l,mid
 16 #define rson root<<1|1,mid+1,r
 17 #define fi first
 18 #define se second
 19 #define ping(x,y) ((x-y)*(x-y))
 20 #define mst(x,y) memset(x,y,sizeof(x))
 21 #define mcp(x,y) memcpy(x,y,sizeof(y))
 22 using namespace std;
 23 #define gamma 0.5772156649015328606065120
 24 #define MOD 1000000007
 25 #define inf 0x3f3f3f3f
 26 #define N 1000010
 27 #define maxn 400005
 28 typedef pair<int,int> PII;
 29 
 30 int n,m,k,tx,ty;  ///tx ty 记录终点位置
 31 char pic[15][15];
 32 int vis[15][15][1<<5|1][6]; ///1,2维表示位置,第3维代表走到当前位置吃了哪些金币
 33 int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}}; ///第4维代表当前有多少金币
 34 int dx[10],dy[10],dcnt;  ///dcnt记录有多少传送门,前两个数组记录位置
 35 struct Node{
 36     int x,y,v,cnt,fg;     ///fg状态压缩表示当前吃了哪些金币
 37     void ini(){           ///v代表当前有多少金币,cnt代表走了几步
 38         v=cnt=fg=0;
 39     }
 40 }node,temp;
 41 void bfs(){
 42     queue<Node>q;
 43     q.push(node);
 44     while(!q.empty()){
 45         node=q.front();q.pop();
 46         int x=node.x;int y=node.y;
 47         if(x==tx&&y==ty){
 48             if(node.v>=k){
 49                 printf("%d\n",node.cnt);
 50                 return;
 51             }
 52             continue;
 53         }
 54         temp=node;
 55         if(pic[x][y]=='P'&&temp.v){    ///走到了有传送门的位置
 56             temp.cnt++;                ///并且有路费可以用传送门
 57             temp.v--;
 58             for(int i=0;i<dcnt;++i){
 59                 if((dx[i]==x&&dy[i]==y))continue;
 60                 int xx=dx[i],yy=dy[i];
 61                 if(vis[xx][yy][temp.fg][temp.v])continue;
 62                 vis[xx][yy][temp.fg][temp.v]=1;
 63                 temp.x=xx;temp.y=yy;
 64                 q.push(temp);
 65             }
 66         }
 67         for(int i=0;i<4;++i){
 68             temp=node;
 69             temp.cnt++;
 70             int xx=x+dir[i][0],yy=y+dir[i][1];
 71             if(xx<1||xx>n||yy<1||yy>m||pic[xx][yy]=='#')continue;
 72             if(isdigit(pic[xx][yy])){   ///走到了有金币的位置
 73                 if(temp.fg&(1<<(pic[xx][yy]-'0'))){  ///金币已经吃过了
 74                     if(!vis[xx][yy][temp.fg][temp.v]){
 75                         vis[xx][yy][temp.fg][temp.v]=1;
 76                         temp.x=xx;temp.y=yy;
 77                         q.push(temp);
 78                     }
 79                 }
 80                 else{        ///金币还没吃过
 81                     temp.fg|=(1<<(pic[xx][yy]-'0'));
 82                     temp.v++;
 83                     if(!vis[xx][yy][temp.fg][temp.v]){
 84                         vis[xx][yy][temp.fg][temp.v]=1;
 85                         temp.x=xx;temp.y=yy;
 86                         q.push(temp);
 87                     }
 88                 }
 89             }
 90             else{
 91                 if(!vis[xx][yy][temp.fg][temp.v]){
 92                     vis[xx][yy][temp.fg][temp.v]=1;
 93                     temp.x=xx;temp.y=yy;
 94                     q.push(temp);
 95                 }
 96             }
 97         }
 98     }
 99     printf("-1\n");
100 }
101 int main(){
102     int i,j,group,Case=0;
103     scanf("%d",&group);
104     while(group--){
105         int gold=0;dcnt=0;///gold是将'C'转换为数字,方便状态压缩
106         mst(vis,0);
107         scanf("%d%d%d",&n,&m,&k);
108         node.ini();
109         for(i=1;i<=n;++i){
110             scanf("%s",pic[i]+1);
111             for(j=1;j<=m;++j){
112                 if(pic[i][j]=='C') pic[i][j]='0'+gold++;
113                 else if(pic[i][j]=='P'){
114                     dx[dcnt]=i;dy[dcnt++]=j; 
115                     vis[i][j][0][0]=1;
116                 }
117                 else if(pic[i][j]=='E'){
118                     tx=i;ty=j;
119                 }
120                 else if(pic[i][j]=='S'){
121                     node.x=i;node.y=j;
122                 }
123             }
124         }
125         bfs();
126     }
127     return 0;
128 }

 

posted @ 2016-06-14 13:06  Kurokey  阅读(143)  评论(0编辑  收藏  举报