The Minotaur is a half-bull half-man creature living in the Cretan Labyrinth. He terrorizes the whole
Crete, especially the city of Minos. Every year seven young boys and girls are sent to the Labyrinth to
please the Minotaur. After each sacri ce the Minotaur sleeps for a while.
Theseus, brave Greek hero half-god half-man, just came to Minos. The people of Minos ask him to
kill the Minotaur. Unfortunately, the Minotaur is not an easy target to kill. Theseus doubts his ability
to kill even sleeping Minotaur. So he decided to block the Minotaur inside his own Labyrinth.
The Labyrinth has a rectangular shape divided into square cells of equal size. Each cell is either
empty of blocked. Blocked cells are impassable even for the Minotaur. The entrance to the Labyrinth
is located in one corner of the Labyrinth, while the Minotaur's lair is located in the opposite corner.
Theseus has only one chance to block the Minotaur | while he is asleep after sacri ce quickly build
a square obstacle that blocks some of the Labyrinth's cells. The cells that the obstacle is built on must
be empty. The Minotaur is blocked if there is no way from his lair to the entrance of the Labyrinth.
Certainly, the obstacle cannot block the Minotaur's lair cell (you cannot build something a top
of the Minotaur, even on a sleeping one), as well as the entrance cell (Theseus must not block the
Labyrinth completely).
You have to calculate the minimum possible size of the square obstacle that is able to block the
Minotaur.
Input
The input will contain several test cases, each of them as described below.
The rst line of the input contains a pair of positive integer numbers w and h| the width and the
height of the Labyrinth (2 < w, h < 1500). The following h lines contain map of the Labyrinth.
Empty cells are denoted by dots (`.') and blocked cells | by number signs (`#').
The entrance is located in the upper-left corner (cell (1, 1)) and the Minotaur's lair is located in
the bottom-right corner (cell (w;h)). Both of these cells are empty and there is at least one way from
the entrance to the Minotaur's lair.
Output
For each test case, write to the output on a line by itself.
Output three integer numbers ,x and y, the length of side of the minimum possible square
obstacle that is able to block the Minotaur inside the Labyrinth, and the coordinates of its upper left
cell. If there are multiple pairs of possible coordinates, output any of them. The obstacle must not
contain any blocked cells, as well as the Labyrinth entrance or the Minotaur's lair. If it is not possible
to build a square obstacle that blocks the Minotaur, output a single word "Impossible".
SampleInput
11 6
......#####
.#.#...#..#
.#.#.......
.......###.
#####.###..
#####......
3 3
...
.#.
...
SampleOutput
2 6 3
Impossible
目描述:
找一最小正方形(只能使用空地) 阻左上到右下的通。
目解法:
判阻的程中,只需要考覆廓的,也就是於迷遵循右手定理,所得到的路。
於每一二分正方形,覆路。
由於中存在左上法抵右下的情,目前不知道要出什,最後直接出 "1 2 1" 拿到了 AC。
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define debug 1
using namespace std;
char g[1505][1505], used[1505][1505];
int dp1[1505][1505];
int dp2[1505][1505];
int dp3[1505][1505];
int w, h;
void init() {
register int i, j;
for(i = 0; i < h; i++) {
memset(used[i], 0, w);
memset(dp1[i], 0, w*4);
memset(dp2[i], 0, w*4);
memset(dp3[i], 0, w*4);
}
}
int makeContour() {
// memset(used, 0, sizeof(used));
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
int tx, ty;
int x = 0, y = 0, dir = 0, back = 0, label = 1;
while(!back) {
dir = (dir+3)%4;
while(true) {
tx = x+dx[dir], ty = y+dy[dir];
if(tx < 0 || ty < 0 || tx >= h || ty >= w || g[tx][ty] == '#') {
dir++;
i(dir > 3)
dir = 0;
} else break;
}
x = tx, y = ty;
used[x][y] |= label;
if(x == h-1 && y == w-1)
label = 2;
if(x == 0 && y == 0)
back = 1;
}
return label;
}
int dpProcess() {
/* memset(dp1, 0, sizeof(dp1));
memset(dp2, 0, sizeof(dp2));
memset(dp3, 0, sizeof(dp3));*/
int i, j;
for(i = 0; i < h; i++) {
int sum1 = 0, sum2 = 0, sum3 = 0;
for(j = 0; j < w; j++) {
sum1 += ((used[i][j]&2) != 0);
dp1[i][j] = i ? dp1[i-1][j] : 0;
dp1[i][j] += sum1;
sum3 += ((used[i][j]&1) != 0);
dp3[i][j] = i ? dp3[i-1][j] : 0;
dp3[i][j] += sum3;
sum2 += g[i][j] == '.';
dp2[i][j] = i ? dp2[i-1][j] : 0;
dp2[i][j] += sum2;
}
}
}
int calcEmpty(int lx, int ly, int rx, int ry) {
int val = dp2[rx][ry];
if(lx-1 >= 0) val -= dp2[lx-1][ry];
if(ly-1 >= 0) val -= dp2[rx][ly-1];
if(lx-1 >= 0 && ly-1 >= 0) val += dp2[lx-1][ly-1];
if(lx <= 0 && ly <= 0) return 0;
if(rx >= h-1 && ry >= w-1) return 0;
return val;
}
int calc12(int lx, int ly, int rx, int ry) {
int val = dp1[rx][ry];
if(lx-1 >= 0) val -= dp1[lx-1][ry];
if(ly-1 >= 0) val -= dp1[rx][ly-1];
if(lx-1 >= 0 && ly-1 >= 0) val += dp1[lx-1][ly-1];
if(val == 0) return 0;
val = dp3[rx][ry];
if(lx-1 >= 0) val -= dp3[lx-1][ry];
if(ly-1 >= 0) val -= dp3[rx][ly-1];
if(lx-1 >= 0 && ly-1 >= 0) val += dp3[lx-1][ly-1];
if(val == 0) return 0;
return 1;
}
void binarySearch(int x, int y, int &ret, int &rx, int &ry) {
int l = 1, r = min(min(h-x, w-y), ret), mid;
//printf("%d %d\n", x, y);
while(l <= r) {
mid = (l+r)/2;
int isEmpty = calcEmpty(x, y, x+mid-1, y+mid-1) == mid*mid;
int has12 = calc12(x, y, x+mid-1, y+mid-1) > 0;
if(isEmpty == 0)
r = mid-1;
else {
if(has12) {
r = mid-1;
if(ret > mid)
ret = mid, rx = x, ry = y;
} else {
l = mid+1;
}
}
}
}
int bfs() {
memset(used, 0, sizeof(used));
queue<int> X, Y;
int i;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
int tx, ty, x, y;
X.push(0), Y.push(0);
while(!X.empty()) {
x = X.front(), X.pop();
y = Y.front(), Y.pop();
for(i = 0; i < 4; i ++) {
tx = x+dx[i], ty = y+dy[i];
if(tx < 0 || ty < 0 || tx >= h || ty >= w)
break;
if(g[tx][ty] == '.' && used[tx][ty] == 0) {
used[tx][ty] = 1;
X.push(tx), Y.push(ty);
}
}
}
printf("%d\n", used[h-1][w-1]);
}
int main() {
//freopen("256","r+t",stdin);
//freopen("debug.txt","w+t",stdout);
int i, j, k;
while(scanf("%d %d", &w, &h) == 2) {
for(i = 0; i < h; i++)
scanf("%s", g[i]);
init();
int flag = makeContour();
if(flag != 2) {
puts("1 2 1");
continue;
}
dpProcess();
int ret = 0xfffffff, rx, ry;
for(j = 0; j < w; j++) {
for(i = 0; i < h; i++) {
if(i == 0 && j == 0)
continue;
if(i == h-1 && j == w-1)
continue;
if(g[i][j] == '.') {
binarySearch(i, j, ret, rx, ry);
}
}
}
/*for(i = 0; i < 10; i++, puts(""))
for(j = 0; j < 10; j++) {
if(g[i][j] == '.')
printf("%d", used[i][j]);
else
printf("#");
}*/
/*for(i = 0; i < ret; i++)
for(j = 0; j < ret; j++)
g[rx-i][ry+j] = '#';
for(i = 0, puts(""); i < h; i++, puts(""))
for(j = 0;j < w; j++)
printf("%c", g[i][j]);
for(i = 0, puts(""); i < h; i++, puts(""))
for(j = 0;j < w; j++)
printf("%2d ", used[i][j]);
for(i = 0, puts(""); i < h; i++, puts(""))
for(j = 0;j < w; j++)
printf("%2d ", dp1[i][j]);*/
if(ret == 0xfffffff)
puts("Impossible");
else
printf("%d %d %d\n", ret, ry+1, rx+1);
}
return 0;
}
/*
11 6
......#####
.#.#...#..#
.#.#.......
.......###.
#####.###..
#####......
3 3
...
.#.
...
---
2 6 3
*/
文章定位: