poj-1104 Robbery

Robbery
Time Limit: 1000MS   Memory Limit: 32768K
Total Submissions: 1249   Accepted: 504

Description

Inspector Robstop is very angry. Last night, a bank has been robbed and the robber has not been caught. And this happened already for the third time this year, even though he did everything in his power to stop the robber: as quickly as possible, all roads leading out of the city were blocked, making it impossible for the robber to escape. Then, the inspector asked all the people in the city to watch out for the robber, but the only messages he got were of the form "We don't see him."
But this time, he has had enough! Inspector Robstop decides to analyze how the robber could have escaped. To do that, he asks you to write a program which takes all the information the inspector could get about the robber in order to find out where the robber has been at which time.

Coincidentally, the city in which the bank was robbed has a rectangular shape. The roads leaving the city are blocked for a certain period of time t, and during that time, several observations of the form "The robber isn't in the rectangle Ri at time ti" are reported. Assuming that the robber can move at most one unit per time step, your program must try to find the exact position of the robber at each time step.

Input

The input contains the description of several robberies. The first line of each description consists of three numbers W, H, t (1 <= W,H,t <= 100) where W is the width, H the height of the city and t is the time during which the city is locked.

The next contains a single integer n (0 <= n <= 100), the number of messages the inspector received. The next n lines (one for each of the messages) consist of five integers ti, Li, Ti, Ri, Bi each. The integer ti is the time at which the observation has been made (1 <= ti <= t), and Li, Ti, Ri, Bi are the left, top, right and bottom respectively of the (rectangular) area which has been observed. (1 <= Li <= Ri <= W, 1 <= Ti <= Bi <= H; the point (1, 1) is the upper left hand corner, and (W, H) is the lower right hand corner of the city.) The messages mean that the robber was not in the given rectangle at time ti.

The input is terminated by a test case starting with W = H = t = 0. This case should not be processed.

Output

For each robbery, first output the line "Robbery #k:", where k is the number of the robbery. Then, there are three possibilities:

If it is impossible that the robber is still in the city considering the messages, output the line "The robber has escaped."

In all other cases, assume that the robber really is in the city. Output one line of the form "Time step : The robber has been at x,y." for each time step, in which the exact location can be deduced. (x and y are the column resp. row of the robber in time step .) Output these lines ordered by time .

If nothing can be deduced, output the line "Nothing known." and hope that the inspector will not get even more angry.

Output a blank line after each processed case.

Sample Input

4 4 5
4
1 1 1 4 3
1 1 1 3 4
4 1 1 3 4
4 4 2 4 4
10 10 3
1
2 1 1 10 10
0 0 0

Sample Output

Robbery #1:
Time step 1: The robber has been at 4,4.
Time step 2: The robber has been at 4,3.
Time step 3: The robber has been at 4,2.
Time step 4: The robber has been at 4,1.

Robbery #2:
The robber has escaped.

Source

Mid-Central European Regional Contest 1999

OJ-ID:
poj-1104

author:
Caution_X

date of submission:
20191024

tags:
模拟

description modelling:
给定一个矩形,现在给定四个点构成一个扫描矩形(扫描矩形在矩形内),表示该扫描矩形范围内没有盗贼,现在给出N个这样的扫描矩形,每个扫描矩形都有对应的时间,表示该扫描发生的时间,现在问能否通过N次扫描判断盗贼的状态(已逃离(离开给定的坐标范围),不确定,或者确定在点(x,y))

major steps to solve it:
vis[t][r][c]=1表示t时刻(r,c)处有盗贼
(1)按照时间正向反向搜索两次,每次扫描的目的在于判断vis[t][r][c]为0的点应不应该是1(因为扫描矩形范围内是1不代表扫描矩形外一定是0,有一些点虽然在扫描矩形外,但它依然必须是1)
(2)完成两次扫描之后遍历时间1~T状态下矩形的点,如果存在某个状态全为1,说明盗贼已经离开了矩形(已逃离),如果某个状态整个矩形只有一点是0,说明该状态下盗贼就在该点。如果所有时间的矩形都扫描过了而且没有得到盗贼的状态,输出不确定时的答案。
正向搜索方式:如果t时刻在(r,c)即vis[t][r][c]=0,那么t-1时刻必然在(r,c)周围(含(r,c))的5个点内,如果这5个点都是1,那么实际上vis[t][r][c]=1。反向搜索类似。

AC code:

#include
#include
#include
using namespace std;
int vis[105][105][105];//vis[t][r][c]=1表示第t时刻r行c列没有盗贼 
int dir[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};
int res[105][2]; //res[i][]表示第i时刻可能的位置 
int W,H,T;
bool inrange(int r,int c)
{
    return (r>=1&&r<=H&&c>=1&&c<=W);
}
void change(int r,int c,int t,int pre_t)
{
    if(vis[t][r][c]) return;
    for(int d=0;d<5;d++) {
        int tmp_r=r+dir[d][0];
        int tmp_c=c+dir[d][1];
        if(inrange(tmp_r,tmp_c)&&!vis[pre_t][tmp_r][tmp_c]) return;
    }
    vis[t][r][c]=1;
    return;
}
int main()
{
    //freopen("input.txt","r",stdin);
    int kase=1;
    while(~scanf("%d%d%d",&W,&H,&T)&&W&&H&&T) {
        printf("Robbery #%d:\n",kase++);
        memset(vis,0,sizeof(vis));
        int N;
        scanf("%d",&N);
        while(N--) {
            int Li,Ri,Ti,Bi,t;
            scanf("%d%d%d%d%d",&t,&Li,&Ti,&Ri,&Bi);
            for(int i=Ti;i<=Bi;i++) {
                for(int j=Li;j<=Ri;j++) {
                    vis[t][i][j]=1;
                }
            }    
        }
        for(int d=0;d<2;d++) {
            for(int i=1;i<=T;i++) {
                for(int r=1;r<=H;r++) {
                    for(int c=1;c<=W;c++) {
                        if(d==0&&i!=1) change(r,c,i,i-1);
                        else change(r,c,T-i+1,T-i+2);
                    }
                }
            }
        }
        int escaped=1,unknown=1;
        memset(res,-1,sizeof(res));
        for(int i=1;i<=T;i++) {
            bool is_allone=true;
            bool is_twice_one=false;
            for(int r=1;r<=H;r++) {
                for(int c=1;c<=W;c++) {
                    if(!vis[i][r][c]) {
                        is_allone=false;
                        if(res[i][0]==-1) {
                            res[i][0]=r;
                            res[i][1]=c;
                        }
                        else if(res[i][0]>=1) {
                            res[i][0]=-1;
                            is_twice_one=true;
                            break;
                        }
                    }
                }
                if(is_twice_one) break;
            }
            if(!is_allone) escaped=0;
            if(res[i][0]>=1) unknown=0;
        }
        if(escaped) printf("The robber has escaped.\n");
        else if(unknown) printf("Nothing known.\n");
        else {
            for(int i=1;i<=T;i++) {
                if(res[i][0]>=1) {
                    printf("Time step %d: The robber has been at %d,%d.\n",i,res[i][1],res[i][0]);
                }
            }
        }
        printf("\n");
    }
    return 0;
}

 

你可能感兴趣的:(poj-1104 Robbery)