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

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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:\n", _++);
 93         printf("%d\n", ret.size());
 94         for(int i = 0; i < ret.size(); i++) {
 95             if(i) printf(" ");
 96             printf("%I64d", ret[i]);
 97         }
 98         printf("\n");
 99     }
100     return 0;
101 }

 

以上是关于[HDOJ5925]Coconuts(BFS,离散化,计数)的主要内容,如果未能解决你的问题,请参考以下文章

[ An Ac a Day ^_^ ] hdu 5925 Coconuts 离散化+BFS求连通块

HDU 5925——Coconuts离散化 + 求连通块(2016 东北赛D题)

2016 长春东北赛---Coconuts(离散化+DFS)

hdu 5929 Coconuts 离散化+dfs

HDOJ4605 Magic Ball Game

HDOJ1010(BFS)