hdu搜索

 

Problem Description

破解字迷之后,你得知Kid将会在展览开始后T分钟内盗取至少一颗宝石,并离开展馆。整个展馆呈矩形分布,划分为N*M个区域,有唯一的入口和出口(不能从出口进入,同样不能从入口出去)。由某个区域可直接移动至相邻四个区域中的一个,且最快需要一分钟。假设Kid进入放有宝石的区域即可盗取宝石,无需耗时。问至少要封锁几个区域(可以封锁放有宝石的区域,但不能封锁入口和出口)才能保证Kid无法完成任务。

Input

输入的第一行有一个整数C,代表有C组测试数据。每组测试数据的第一行有三个整数N,M,T(2<=N,M<=8,T>0)。接下来N行M列为展馆布置图,其中包括:

'S':入口
'E':出口
'J':放有宝石的区域,至少出现一次
'.':空白区域
'#':墙

Output

对每组测试数据,输出至少要封锁的区域数。

Sample Input

2
5 5 5
SJJJJ
..##J
.JJJJ
.J...
EJ...
5 5 6
SJJJJ
..##J
.JJJJ
.J...
EJ...

Sample Output

0
2

代码:

 

/*
 

因为 地图只有 8*8 ,并且最多只需要堵 4个地方 (起点或者终点的 四个方向)。。。

 

所以暴力枚举 前3个点的堵法,都不能堵的话,就输出4。

 

时间 O((8*8) * (8*8) * (8*8) * (8*8) ),约1600MS 。。。


*/


#include
#include
#include

using namespace std;

struct Node{
 int x,y,has;
 Node(){}
 Node(int a,int b,int c){x=a,y=b,has=c;}
}que[200];

int fx[]={1,-1,0,0};
int fy[]={0,0,1,-1};

int res,n,m,T;
char map[10][10];
int si,sj;
int vis[8][8][2];

int bfs(){
 int s,t,k,nx,ny,has;
 memset(vis,-1,sizeof(vis));
 que[s=t=0]=Node(si,sj,0);
 vis[si][sj][0]=0;
 while(s<=t){
  Node no=que[s++];
  if(map[no.x][no.y]=='E' && no.has) return 0;
  if(vis[no.x][no.y][no.has]>=T) continue;
  for(k=0;k<4;k++){
   nx=no.x+fx[k];
   ny=no.y+fy[k];
   has=no.has;
   if(nx<0 || nx>=n || ny<0 || ny>=m) continue;
   if(map[nx][ny]=='#') continue;
   if(map[nx][ny]=='J') has=1;
   if(vis[nx][ny][has]!=-1) continue;
   vis[nx][ny][has]=vis[no.x][no.y][no.has]+1;
   que[++t]=Node(nx,ny,has);
  }
 }
 return 1;
}

int dfs(int v){
 if(v==0) return bfs();
 for(int i=0;i   for(int j=0;j    if(map[i][j]=='.' || map[i][j]=='J'){
    char tmp=map[i][j];
    map[i][j]='#';
    if(dfs(v-1)) return 1;
    map[i][j]=tmp;
   }
 return 0;
}

int main(){
 int t,i,j;
 scanf("%d",&t);
 while(t--){
  scanf("%d%d%d",&n,&m,&T);
  for(i=0;i    scanf("%s",map[i]);
   for(j=0;j     if(map[i][j]=='S')
     si=i,sj=j;
  }
  if(bfs()) puts("0");
  else if(dfs(1)) puts("1");
  else if(dfs(2)) puts("2");
  else if(dfs(3)) puts("3");
  else puts("4");
 }
 return 0;
}

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