HDU 1983 - Kaitou Kid - The Phantom Thief (2)

来源:互联网 发布:2016淘宝手机店铺装修 编辑:程序博客网 时间:2024/05/11 13:04

 

题目地址: 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;}/*55 5 10000S#JJJ.#JJJ..JJJ..###E....5 5 1000S#JJJ.#JJJ.#JJJ.####EJ...*/