模拟赛 密室逃脱(时间限制:1s;空间限制:256MB)

Problem Description

即使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,s<=5

题解

经典的分层图搜索,应为s很小,可以状压或暴搜走那些s,然后将这些s看做‘.’用广搜在分层图上跑。
#include
#include
#include
#include
#include
#include
#define inf 1<<30
#define mod 100002
using namespace std;
int n,m,sx,sy,ex,ey,tot;
struct fang{int x,y;} a[10];
char ch[105][105];
int f[102][102][10],ans=inf;
int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
int qx[100005],qy[100005],qv[100005];
void init()
{
	scanf("%d%d",&n,&m);
	int i,j;
	for(i=1;i<=n;i++)
	   {scanf("%s",ch[i]+1);
	    for(j=1;j<=n;j++)
	       {if(ch[i][j]=='K') {sx=i;sy=j;}
		    else if(ch[i][j]=='T') {ex=i; ey=j;}
		    else if(ch[i][j]=='S')
		       {tot++; a[tot].x=i; a[tot].y=j;}
		   }
	   }
}
bool check(int x,int y,int v)
{
	if(x<1||y<1||x>n||y>n) return true;
	if(ch[x][y]=='#'||f[x][y][v]!=-1) return true;
	return false;
}
void bfs()
{
	memset(f,-1,sizeof(f));
	qx[0]=sx; qy[0]=sy; qv[0]=0;
	int t=0,w=1,i,xn,yn,vn,xt,yt,vt;
	f[sx][sy][0]=0;
	while(t!=w)
	   {xn=qx[t]; yn=qy[t]; vn=qv[t]; t=(t+1)%mod;
	    for(i=0;i<4;i++)
	       {xt=xn+xx[i]; yt=yn+yy[i]; vt=vn;
			if(check(xt,yt,vt)) continue;
			if(vn+1==ch[xt][yt]-'0') vt++;
		    f[xt][yt][vt]=f[xn][yn][vn]+1;
		    qx[w]=xt; qy[w]=yt; qv[w]=vt;
		    w=(w+1)%mod;
		   }
	   }
}
void dfs(int w,int ct)
{
	if(w==tot+1)
	   {bfs();
	    if(f[ex][ey][m]!=-1) ans=min(ans,ct+f[ex][ey][m]);
	    return ;
	   }
	ch[a[w].x][a[w].y]='.';
	dfs(w+1,ct+1);
	ch[a[w].x][a[w].y]='#';
	dfs(w+1,ct);
}
int main()
{
	freopen("maze.in","r",stdin);
	freopen("maze.out","w",stdout);
	init(); dfs(1,0);
	if(ans!=inf)printf("%d\n",ans);
	else puts("impossible");
	return 0;
}

你可能感兴趣的:(搜索)