// Robbery (robbery) // PC/ultraviolet A IDs: 111205/707, popularity: B, success rate: average level: 3 // verdict: accepted // submission date: 2011-11-04 // UV Run Time: 0.036 S // copyright (c) 2011, Qiu. Metaphysis # Yeah dot net // [solution] // tip: How to Create a graph to depict time and space at the same time? How to efficiently traverse to determine possible locations? If you have solved these two problems, this question will be solved! # Include <iostream> using namespace STD; # define maxn 100 # define unobserved 0 # define observed 1 # define reachable 2 # define I _am_here 3int width, height, timelocked; int grid [maxn + 1] [maxn + 1] [maxn + 1]; int offset [5] [2] = {0, 0}, {-1, 0 },{ 0,-1 },{ 1, 0 },{ 0, 1 }}; // first search for the final moment, locate the reachable location, and mark it. Void backward_dfs (INT time, int y, int X) {If (time = 1) {grid [time] [y] [x] = reachable; return ;} for (INT I = 0; I <5; I ++) {int tmpy = Y + offset [I] [0]; int tmpx = x + offset [I] [1]; if (1 <= tmpy & tmpy <= height & 1 <= tmpx & tmpx <= width) if (grid [time-1] [tmpy] [tmpx] = unobserved) {grid [time] [y] [x] = reachable; backward_dfs (time-1, tmpy, tmpx);} else if (grid [time-1] [tmpy] [tmpx] = reachable) g Rid [time] [y] [x] = reachable ;}// search from the past to the next and mark the possible positions. Void forward_dfs (INT time, int y, int X) {If (time = timelocked) {grid [time] [y] [x] = I _am_here; return ;} for (INT I = 0; I <5; I ++) {int tmpy = Y + offset [I] [0]; int tmpx = x + offset [I] [1]; if (1 <= tmpy & tmpy <= height & 1 <= tmpx & tmpx <= width) if (grid [Time + 1] [tmpy] [tmpx] = reachable) {grid [time] [y] [x] = I _am_here; forward_dfs (Time + 1, tmpy, tmpx);} else if (grid [Time + 1] [tmpy] [tmpx] = I _am _ Here) grid [time] [y] [x] = I _am_here ;}} int main (INT AC, char * AV []) {INT cases = 1; int messages; int current, left, top, right, bottom; while (CIN> width> height> timelocked, width | height | timelocked) {cout <"robbery #" <cases ++ <": \ n"; for (int t = 1; t <= timelocked; t ++) for (INT y = 1; y <= height; y ++) for (INT x = 1; x <= width; X ++) grid [T] [y] [x] = unobserved; // read the block range of the slice at each time. The robbers will not be at this time.. Cin> messages; For (INT I = 1; I <= messages; I ++) {CIN> current> left> top> right> bottom; for (INT y = top; y <= bottom; y ++) for (INT x = left; x <= right; X ++) grid [current] [y] [x] = observed;} // traverse depth first from the last time slice. Assume that at the moment t, the robber is in the position (width, // height), then t-1 at the last moment, the robber can only be in (width-1, height ), // (width + 1, height), (width, height-1), (width, height + 1) // (width, height) one of the five positions. Note that you need to search in both positive and negative directions to determine the possible locations on the // path. For (INT y = 1; y <= height; y ++) for (INT x = 1; x <= width; X ++) if (grid [timelocked] [y] [x] = unobserved) backward_dfs (timelocked, Y, x); // a forward search is performed to determine a feasible position. For (INT y = 1; y <= height; y ++) for (INT x = 1; x <= width; X ++) if (grid [1] [y] [x] = reachable) forward_dfs (1, Y, x); // The output is determined based on the number of possible time slices. Bool nothing = true; pair <int, int> location; For (int t = 1; t <= timelocked; t ++) {int exactlocation = 0; for (INT y = 1; y <= height; y ++) {for (INT x = 1; x <= width; X ++) if (grid [T] [y] [x] = I _am_here) {exactlocation ++; location = make_pair (x, y); If (exactlocation> 1) break ;} if (exactlocation> 1) break;} If (exactlocation = 0) {cout <"the robber has escaped. \ n "; nothing = false; break;} If (exactlocation = 1) {cout <" time step "<t <":"; cout <"the robber has been at"; cout <location. first <"," <location. second; cout <". \ n "; nothing = false ;}} if (nothing) cout <" nothing known. \ n "; cout <" \ n ";} return 0 ;}