密室逃脱(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:
3 1
K.S
##1
1#T
Sample1.out
5
Sample2.in
3 1
K#T
.S#
1#.
Sample2.out
Impossible
Sample3.in
3 2
K#T
.S.
21.
Sample3.out
8
样例3说明:
要先取钥匙1,再取钥匙2。地图上可能有多个同一种钥匙,#为墙壁即不可走.
数据范围:
0 < N <= 100, 0<=M<=9
暴力dfs+bfs
dfs枚举走几个问题,bfs求最短路
1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 6 const int INF=0x7fffffff; 7 8 struct NODE 9 { 10 int x,y,t; 11 }; 12 13 int n,m; 14 char A[105][105]; 15 int kx,ky,tx,ty,cnt,ans=INF; 16 int x[10],y[10]; 17 int F[105][105][10]; 18 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0}; 19 20 void bfs() 21 { 22 memset(F,-1,sizeof(F)); 23 queue<NODE> Q; 24 Q.push((NODE){kx,ky,0}); 25 F[kx][ky][0]=0; 26 while(!Q.empty()) 27 { 28 NODE q=Q.front();Q.pop(); 29 for(int i=0;i<4;i++) 30 { 31 int x=q.x+xx[i],y=q.y+yy[i],t=q.t; 32 if(x<1||x>n||y<1||y>n) continue; 33 if(A[x][y]=='#'||F[x][y][t]!=-1) continue; 34 if(t+1==A[x][y]-'0') t++; 35 F[x][y][t]=F[q.x][q.y][q.t]+1; 36 Q.push((NODE){x,y,t}); 37 } 38 } 39 } 40 41 void dfs(int now,int k) 42 { 43 if(now==cnt+1) 44 { 45 bfs(); 46 if(F[tx][ty][m]!=-1) 47 ans=min(ans,k+F[tx][ty][m]); 48 return; 49 } 50 A[x[now]][y[now]]='.'; 51 dfs(now+1,k+1); 52 A[x[now]][y[now]]='#'; 53 dfs(now+1,k); 54 } 55 56 int main() 57 { 58 cin>>n>>m; 59 for(int i=1;i<=n;i++) 60 { 61 scanf("%s",A[i]+1); 62 for(int j=1;j<=n;j++) 63 { 64 switch(A[i][j]) 65 { 66 case 'K': 67 kx=i;ky=j; 68 break; 69 case 'T': 70 tx=i;ty=j; 71 break; 72 case 'S': 73 cnt++; 74 x[cnt]=i;y[cnt]=j; 75 break; 76 } 77 } 78 } 79 dfs(1,0); 80 if(ans==INF) 81 cout<<"Impossible"<<endl; 82 else 83 cout<<ans<<endl; 84 return 0; 85 }