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

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

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

题解:离散化后 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 }
时间: 2024-08-13 09:31:41

[HDOJ5925]Coconuts(BFS,离散化,计数)的相关文章

HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 524    Accepted Submission(s): 151 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams abou

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

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5925 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams about eating. One day, TanBig dreams of a field of coconuts, and the field looks like a large chessb

hdu 2771(uva 12171) Sculpture bfs+离散化

题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处在于求整个雕塑的外表面积和雕塑内部可能出现四个长方体所搭成的空心.空心不能计算到表面积中,可是计算整体积却要计入,于是直接bfs或者dfs不优点理.于是,能够想到直接统计整个雕塑外围的全部小方块.就可以非常方便地求出雕塑地表面积和体积(雕塑地整体积==整个空间地体积-外围想方块的体积),另一点就是因

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

东北赛根本就没看懂的的题目…… 也用到了离散化 1e9的x y范围 200个坏点 很典型的离散化数据范围 还是不太为什么离散化的遍历下标都要从1开始…… 所以说只做这道题对离散化的理解还不是很深刻…… 因为可能换一道题又不会了 还是要多做啊 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<

洛谷 1144 最短路计数 bfs

洛谷1144 最短路计数 传送门 其实这道题目的正解应该是spfa里面加一些处理,,然而,,然而,,既然它是无权图,,那么就直接bfs了,用一个cnt记录一下每一个点的方案数,分几种情况讨论一下转移,最后输出cnt即为结果.. 题目中所说的重边和自环啥的没看出来有啥影响.. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int maxn = 100000 + 500;

hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1110    Accepted Submission(s): 280 Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all peo

Codeforces243C-Colorado Potato Beetle(离散化+bfs)

Old MacDonald has a farm and a large potato field, (1010 + 1) × (1010 + 1) square meters in size. The field is divided into square garden beds, each bed takes up one square meter. Old McDonald knows that the Colorado potato beetle is about to invade

离散化+BFS HDOJ 4444 Walk

题目传送门 1 /* 2 题意:问一个点到另一个点的最少转向次数. 3 坐标离散化+BFS:因为数据很大,先对坐标离散化后,三维(有方向的)BFS 4 关键理解坐标离散化,BFS部分可参考HDOJ_1728 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include <queue> 10 #include <vector> 11 #include

HDU 4444 离散化+bfs 注意细节

Walk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1972    Accepted Submission(s): 308 Problem Description Biaoge is planning to walk to amusement park. The city he lives can be abstracted as