题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1983
去年做时没做出来,木有思路。
今年再次碰到这题,初看还是木有思路。仔细一想,先暴力一发。。。 果然过了。。。
=======================================================================================================
因为 地图只有 8*8 ,并且最多只需要堵 4个地方 (起点或者终点的 四个方向)。。。
所以暴力枚举 前3个点的堵法,都不能堵的话,就输出4。
时间 O((8*8) * (8*8) * (8*8) * (8*8) ),约1600MS 。。。
#include<iostream>
#include<cstdio>
#include<cstring>
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<n;i++)
for(int j=0;j<m;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<n;i++){
scanf("%s",map[i]);
for(j=0;j<m;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;
}
=======================================================================================
后来想了一下,只需要先找到一条合理路径(取到金子,并且能够在T时刻前达到终点)。。。
那么我们枚举的范围,就可以缩减为这条路径上的所有点。。。(31 MS)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct Node{
int x,y,has,p;
int rx[64],ry[64];
Node(){}
Node(int a,int b,int c,int v,int xx,int yy){x=a,y=b,has=c,p=v,rx[v]=xx,ry[v]=yy;}
}que[1000];
int fx[]={1,-1,0,0};
int fy[]={0,0,1,-1};
int res,n,m,T;
char map[10][10];
int si,sj,ei,ej;
bool vis[8][8][2];
void dfs(int num){
if(num>=res) return ;
int s,t,k;
Node ne,no;
memset(vis,false,sizeof(vis));
que[s=t=0]=Node(si,sj,0,0,si,sj);
vis[si][sj][0]=true;
while(s<=t){
no=que[s++];
if(map[no.x][no.y]=='E' && no.has) break;
if(no.p>=T) continue;
for(k=0;k<4;k++){
ne=no;
ne.x+=fx[k],ne.y+=fy[k],ne.p++;
if(ne.x<0 || ne.x>=n || ne.y<0 || ne.y>=m) continue;
if(map[ne.x][ne.y]=='#') continue;
if(map[ne.x][ne.y]=='J') ne.has=1;
if(vis[ne.x][ne.y][ne.has]) continue;
vis[ne.x][ne.y][ne.has]=true;
ne.rx[ne.p]=ne.x;
ne.ry[ne.p]=ne.y;
que[++t]=ne;
}
}
if(vis[ei][ej][1]){
for(k=1;k<no.p;k++)
if(map[no.rx[k]][no.ry[k]]=='.' || map[no.rx[k]][no.ry[k]]=='J'){
char tmp=map[no.rx[k]][no.ry[k]];
map[no.rx[k]][no.ry[k]]='#';
dfs(num+1);
map[no.rx[k]][no.ry[k]]=tmp;
}
}
else res=num;
}
int main(){
int t,i,j;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&T);
for(i=0;i<n;i++){
scanf("%s",map[i]);
for(j=0;j<m;j++)
if(map[i][j]=='S')
si=i,sj=j;
else if(map[i][j]=='E')
ei=i,ej=j;
}
res=4;
dfs(0);
printf("%d\n",res);
}
return 0;
}
/*
5
5 5 10000
S#JJJ
.#JJJ
..JJJ
..###
E....
5 5 1000
S#JJJ
.#JJJ
.#JJJ
.####
EJ...
*/