题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21261
思路:此题需要记忆化搜索,dp[x][y][t]表示当前状态下是否是否有可能点(x,y)上有贼,0表示不可能,1表示可能,然后及时记忆化搜索。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 111 8 typedef pair<int,int>PP; 9 10 int n,m,Time,cnt; 11 int dp[MAXN][MAXN][MAXN]; 12 int dir[5][2]={{0,-1},{-1,0},{0,1},{1,0},{0,0}}; 13 vector<vector<PP> >ans; 14 15 bool Judge(int x,int y) 16 { 17 if(x>=1&&x<=m&&y>=1&&y<=n)return true; 18 return false; 19 } 20 21 bool dfs(int x,int y,int t) 22 { 23 if(dp[x][y][t]!=-1)return dp[x][y][t]; 24 if(t>=Time){ 25 cnt++; 26 ans[t].push_back(make_pair(x,y)); 27 return dp[x][y][t]=1; 28 } 29 dp[x][y][t]=0; 30 for(int i=0;i<5;i++){ 31 int xx=x+dir[i][0],yy=y+dir[i][1]; 32 if(!Judge(xx,yy))continue; 33 if(dfs(xx,yy,t+1)){ 34 dp[x][y][t]=1; 35 } 36 } 37 if(dp[x][y][t]==1){ 38 ans[t].push_back(make_pair(x,y)); 39 } 40 return dp[x][y][t]; 41 } 42 43 44 int main() 45 { 46 int T,t,a,b,c,d,Cas=1,flag; 47 while(~scanf("%d%d%d",&n,&m,&Time)){ 48 if(n==0&&m==0&&Time==0)break; 49 scanf("%d",&T); 50 memset(dp,-1,sizeof(dp)); 51 while(T--){ 52 scanf("%d%d%d%d%d",&t,&a,&b,&c,&d); 53 for(int i=b;i<=d;i++) 54 for(int j=a;j<=c;j++) 55 dp[i][j][t]=0; 56 } 57 ans.clear(); 58 ans.resize(MAXN); 59 cnt=flag=0; 60 for(int i=1;i<=m;i++){ 61 for(int j=1;j<=n;j++){ 62 if(dp[i][j][1]==-1)dfs(i,j,1); 63 } 64 } 65 printf("Robbery #%d: ",Cas++); 66 if(cnt==0){ 67 puts("The robber has escaped."); 68 }else { 69 for(int i=1;i<=Time;i++){ 70 if((int)ans[i].size()==1){ 71 flag=1; 72 printf("Time step %d: The robber has been at %d,%d. ",i,ans[i][0].second,ans[i][0].first); 73 } 74 } 75 if(!flag)puts("Nothing known."); 76 } 77 puts(""); 78 } 79 return 0; 80 } 81 82 83 84 85 86 87 88