[HDOJ5925]Coconuts(BFS,离散化,计数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5925

题意:一个 R×C 的棋盘,有 n200 个格子是黑的,其他都是白的,问所有白色格子构成的四联通块有多大。

题解:离散化后 BFS。

这个离散化以后会有一个问题,因为这个题要统计每一个连通块里的点数,所以我在离散化的时候顺便对每一对相邻的障碍物之间有多少个空白做了计数,这样在bfs的时候只需要加上乘积就行了。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 typedef long long LL;
  5 const int maxn = 100100;
  6 const int maxm = 3048;
  7 const int dx[5] = {0,0,1,-1};
  8 const int dy[5] = {1,-1,0,0};
  9 typedef struct Point {
 10     int x, y;
 11     Point(){}
 12     Point(int x,int y):x(x),y(y){}
 13 }Point;
 14 int vis[maxm][maxm];
 15 Point p[maxm];
 16 int K, N, M, n, m;
 17 int tx[maxn], ty[maxn];
 18 LL vx[maxn], vy[maxn];
 19 vector<LL> ret;
 20 queue<Point> q;
 21 int d[maxn];
 22 
 23 inline bool ok(int x, int y) {
 24     return x >= 1 && x <= n && y >= 1 && y <= m;
 25 }
 26 
 27 int gao(int* x, LL* vx, int& w, bool flag) {
 28     sort(x, x+w);
 29     w = unique(x, x+w) - x;
 30     int t = 1;
 31     d[0] = x[0];
 32     for(int i = 1; i < w; i++) {
 33         if(x[i] != x[i-1] + 1) d[t++] = x[i-1] + 1;
 34         d[t++] = x[i];
 35     }
 36     sort(d, d+t);
 37     int mx = t - 1;
 38     for(int i = 1; i < t; i++) {
 39         vx[i] = d[i] - d[i-1];
 40     }
 41     for(int i = 0; i < K; i++) {
 42         if(flag) p[i].x = lower_bound(d, d+t, p[i].x) - d;
 43         else p[i].y = lower_bound(d, d+t, p[i].y) - d;
 44     }
 45     return mx;
 46 }
 47 
 48 LL bfs(int x, int y) {
 49     while(!q.empty()) q.pop();
 50     q.push(Point(x, y)); vis[x][y] = 1;
 51     LL cnt = vx[x] * vy[y];
 52     while(!q.empty()) {
 53         Point t = q.front(); q.pop();
 54         for(int i = 0; i < 4; i++) {
 55             int tx = t.x + dx[i];
 56             int ty = t.y + dy[i];
 57             if(!ok(tx, ty)||vis[tx][ty]) continue;
 58             vis[tx][ty] = 1; cnt += vx[tx] * vy[ty];
 59             q.push(Point(tx, ty));
 60         }
 61     }
 62     return cnt;
 63 }
 64 
 65 int main() {
 66     // freopen("in", "r", stdin);
 67     int T, _ = 1;
 68     scanf("%d", &T);
 69     while(T--) {
 70         ret.clear(); N = 0, M = 0;
 71         memset(vis, 0, sizeof(vis));
 72         scanf("%d%d%d",&n,&m,&K);
 73         tx[N++] = 0; tx[N++] = n;
 74         ty[M++] = 0; ty[M++] = m;
 75         for(int i = 0; i < K; i++) {
 76             scanf("%d%d",&p[i].x,&p[i].y);
 77             tx[N++] = p[i].x; tx[N++] = p[i].x - 1;
 78             ty[M++] = p[i].y; ty[M++] = p[i].y - 1;
 79         }
 80         n = gao(tx, vx, N, 1); m = gao(ty, vy, M, 0);
 81         for(int i = 0; i < K; i++) {
 82             // BUG
 83             // if(p[i].x >= maxm || p[i].y >= maxm) while(1);
 84             vis[p[i].x][p[i].y] = 1;
 85         }
 86         for(int i = 1; i <= n; i++) {
 87             for(int j = 1; j <= m; j++) {
 88                 if(!vis[i][j]) ret.push_back(bfs(i, j));
 89             }
 90         }
 91         sort(ret.begin(), ret.end());
 92         printf("Case #%d:
", _++);
 93         printf("%d
", ret.size());
 94         for(int i = 0; i < ret.size(); i++) {
 95             if(i) printf(" ");
 96             printf("%I64d", ret[i]);
 97         }
 98         printf("
");
 99     }
100     return 0;
101 }
原文地址:https://www.cnblogs.com/kirai/p/5936274.html