考细心的模拟,开始的时候,没有注意到不能有其他窗遮盖这个条件,把模拟写成了只要能看到全部窗框就算是满足要求,所以WA了一次。不过很快就找到这个bug了,AC。
做法其实很简单,只要沿着边框走一遍就可以了。
代码如下:
View Code
1 #define _clr(x) memset(x, 0, sizeof(x)) 2 #define REP(i, n) for (int i = 0; i < (n); i++) 3 #define REP_1(i, n) for (int i = 1; i <= (n); i++) 4 5 const int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 6 bool vis[N][N]; 7 char mat[N][N]; 8 9 bool test(int x, int y, char ch) { 10 _clr(vis); 11 int minx = inf, miny = inf, maxx = x, maxy = y; 12 int cx = x, cy = y, cnt = 0; 13 while (!vis[cx][cy]) { 14 // cout << cx << ends << cy << ends << cnt << endl; 15 cnt++; 16 minx = min(minx, cx), miny = min(miny, cy); 17 vis[cx][cy] = true; 18 REP(i, 4) { 19 int nx = cx + dir[i][0], ny = cy + dir[i][1]; 20 if (vis[nx][ny] || mat[nx][ny] != ch) continue; 21 cx = nx, cy = ny; 22 break; 23 } 24 } 25 if (cnt >= 8) { 26 REP(d, 4) { 27 if (cx + dir[d][0] == x && cy + dir[d][1] == y) { 28 INC(i, minx + 1, maxx - 1) { 29 INC(j, miny + 1, maxy - 1) { 30 if (mat[i][j] != '.') return false; 31 } 32 } 33 return true; 34 } 35 } 36 } 37 return false; 38 } 39 40 int mx[30], my[30]; 41 42 int main() { 43 // freopen("in", "r", stdin); 44 int n, m; 45 while (~scanf("%d%d", &n, &m) && (n + m)) { 46 _clr(mat); 47 _clr(mx); 48 _clr(my); 49 REP_1(i, n) { 50 scanf("%s", &mat[i][1]); 51 REP_1(j, m) { 52 if (mat[i][j] != '.') { 53 // cout << i << ends << j << endl; 54 int id = mat[i][j] - 'A'; 55 mx[id] = i, my[id] = j; 56 } 57 } 58 } 59 REP(i, 26) { 60 // cout << mx[i] << ends << my[i] << endl; 61 if (mx[i] || my[i]) { 62 if (test(mx[i], my[i], i + 'A')) putchar(i + 'A'); 63 } 64 } 65 puts(""); 66 } 67 return 0; 68 }
——written by Lyon