Question address: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1983
I did not do it last year.
I encountered this question again this year. I still have some ideas at the beginning. Think twice, let alone a brute force attack... Sure enough...
========================================================== ========================================================== ======================================
Because the map is only 8*8, and only four locations need to be blocked at most (the four directions of the start point or the end point )...
Therefore, if none of the above three points of brute force enumeration can be blocked, output 4.
Time O (8*8) * (8*8) * (8*8) * (8*8), about 1600 ms...
#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;}
========================================================== ========================================================== ========
After thinking about it, you just need to find a reasonable path (get the gold and reach the end point before t moment )...
Then the enumerated range can be reduced to all vertices on the path... (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...*/