hdu 1429 bfs+状压

题意:这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始 Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一 个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮 他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。

每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:

. 代表路
* 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J

 

记得去年网赛有这样一题,当时不会状压,搞不出来,现在看起来还是很水的

 

得到钥匙的状态用二进制表示,比如有A钥匙即为1,有A,C钥匙即为101

  1 #include<cstdio>

  2 #include<iostream>

  3 #include<algorithm>

  4 #include<cstring>

  5 #include<cmath>

  6 #include<queue>

  7 #include<map>

  8 using namespace std;

  9 #define MOD 1000000007

 10 const int INF=0x3f3f3f3f;

 11 const double eps=1e-5;

 12 #define cl(a) memset(a,0,sizeof(a))

 13 #define ts printf("*****\n");

 14 const int MAXN=1005;

 15 int vis[25][25][1025];

 16 char s[25][25];

 17 int d[4][2]={1,0,0,1,-1,0,0,-1};

 18 int n,m,tt,time;

 19 struct node

 20 {

 21     int x,y,t,key;

 22     node(){}

 23     node(int xx,int yy,int tt,int kk)

 24     {

 25         x=xx,y=yy,t=tt,key=kk;

 26     }

 27 }st,ed;

 28 void bfs()

 29 {

 30     node now,next;

 31     queue<node> q;

 32     q.push(node(st.x,st.y,0,0));

 33     vis[st.x][st.y][0]=1;

 34     while(!q.empty())

 35     {

 36         now=q.front();

 37         q.pop();

 38         if(now.x==ed.x&&now.y==ed.y)

 39         {

 40             if(now.t<time)

 41             {

 42                 printf("%d\n",now.t);

 43                 return;

 44             }

 45             else

 46                 break;

 47         }

 48         for(int i=0;i<4;i++)

 49         {

 50             next.x=now.x+d[i][0];

 51             next.y=now.y+d[i][1];

 52             next.t=now.t+1;

 53             next.key=now.key;

 54             if(next.x>=0&&next.y>=0&&next.x<n&&next.y<m&&s[next.x][next.y]!='*')

 55             {

 56                 if('A'<=s[next.x][next.y]&&s[next.x][next.y]<='J')

 57                 {

 58                     int key=1<<(s[next.x][next.y]-'A');

 59                     if((next.key&key)&&!vis[next.x][next.y][next.key])

 60                     {

 61                         vis[next.x][next.y][next.key]=1;

 62                         q.push(next);

 63                     }

 64                 }

 65                 else if(s[next.x][next.y]>='a'&&s[next.x][next.y]<='j')

 66                 {

 67                     int key=(1<<(s[next.x][next.y]-'a'));

 68                     next.key=(next.key|key);

 69                     if(!vis[next.x][next.y][next.key])

 70                     {

 71                         vis[next.x][next.y][next.key]=1;

 72                         q.push(next);

 73                     }

 74                 }

 75                 else

 76                 {

 77                     if(!vis[next.x][next.y][next.key])

 78                     {

 79                         vis[next.x][next.y][next.key]=1;

 80                         q.push(next);

 81                     }

 82                 }

 83             }

 84         }

 85     }

 86     printf("-1\n");

 87 

 88 }

 89 int main()

 90 {

 91     int i,j,k;

 92     #ifndef ONLINE_JUDGE

 93     freopen("1.in","r",stdin);

 94     #endif

 95     while(scanf("%d%d%d",&n,&m,&time)!=EOF)

 96     {

 97         for(i=0;i<n;i++)

 98         {

 99             scanf("%s",s[i]);

100             for(j=0;j<m;j++)

101             {

102                 if(s[i][j]=='@')    st.x=i,st.y=j;

103                 if(s[i][j]=='^')    ed.x=i,ed.y=j;

104             }

105         }

106         memset(vis,0,sizeof(vis));

107         bfs();

108     }

109 }

 

你可能感兴趣的:(HDU)