【宽搜变例】【按照一定次序】密室逃脱

来源:互联网 发布:unity3d上海 编辑:程序博客网 时间:2024/06/11 20:54

密室逃脱(maze.*)

    即使czhou没有派出最强篮球阵容,机房篮球队还是暴虐了校篮球队。为了不打击校篮球队信心,czhou决定改变训练后的活动。近来,江大掌门的徒弟徒孙们纷纷事业有成,回到母校为机房捐钱捐物。财大气粗的机房组收回了五层六层的所有教室。Czhou决定将六层的教室改造为智能密室逃脱活动室。

    每天傍晚,神牛们可以依次逐个进入游玩。我们简单的将教室分割为n*n个房间,K是你初始所在房间,T是你最终逃脱的房间。如果你想要逃脱房间,你必须依次找到m把钥匙。我们假定你从一个房间进入另一个房间需要花费1的时间。当然某些房间有些特殊的问题(地图上S表示)需要回答才能通过,对于机智的众牛们来说,这些问题根本不是问题。我们假定众牛们花费1的时间解决问题。(主要是出题的人表述不清,导致众牛理解困难;当然问题只需要回答一次,下次再次进入房间不需要回答了)

Input:maze.in

    第一行两个数字n,m

    接下来n*n描述地图

Output:maze.out

    需要最少时间逃脱密室。若无解输出impossible

Sample1.in:

31

K.S

##1

1#T

Sample1.out

5

Sample2.in

3  1

K#T

.S#

1#.

Sample2.out

Impossible

Sample3.in

32

K#T

.S.

21.

Sample3.out

8

样例3说明:

    要先取钥匙1,再取钥匙2。地图上可能有多个同一种钥匙,#为墙壁即不可走.

数据范围:

    0 < N <= 100, 0<=M<=9


//0.5s,900kb#include<cstdio>#include<cstring>#include<iostream>#include<queue>#define inf 0x7fffffffusing namespace std;struct pos{int x,y,k;};char map[101][101];int n,m,ans=inf,qesn=0;int f[101][101][10],tx[4]={0,-1,0,1},ty[4]={1,0,-1,0};pos st,ed,qes[9];int mymin(int a,int b){return a>b?b:a;}void bfs(void){memset(f,-1,sizeof(f));f[st.x][st.y][0]=0;queue<pos> q;//用滚动数组更快 q.push(st);while(q.empty()==false){pos fr=q.front();for(int i=0;i<=3;i++){pos ne;ne.x=fr.x+tx[i];ne.y=fr.y+ty[i];ne.k=fr.k;if(map[ne.x][ne.y]==ne.k+1) ne.k++;if(map[ne.x][ne.y]==0 or f[ne.x][ne.y][ne.k]!=-1) continue;f[ne.x][ne.y][ne.k]=f[fr.x][fr.y][fr.k]+1;q.push(ne);}q.pop();}}void dfs(int k,int l)//枚举每一个S {if(k==qesn+1){bfs();if(f[ed.x][ed.y][m]!=-1)ans=mymin(ans,l+f[ed.x][ed.y][m]);return;}map[qes[k].x][qes[k].y]=11;dfs(k+1,l+1);map[qes[k].x][qes[k].y]=0;dfs(k+1,l);}int main(){scanf("%d %d",&n,&m);for(int i=1;i<=n;i++){char s[110];scanf("%s",s+1);for(int j=1;j<=n;j++){map[i][j]=s[j]!='#'?11:0;if(s[j]=='K') {st.x=i;st.y=j;}if(s[j]=='T') {ed.x=i;ed.y=j;}if(s[j]=='S') {qesn++;qes[qesn].x=i;qes[qesn].y=j;}if(s[j]>='0' and s[j]<='9') map[i][j]=s[j]-'0';}}dfs(1,0);if(ans==inf) printf("impossible");else printf("%d",ans);}


0 0