HDU 5925 Coconuts(离散化+bfs, 好题)

来源:互联网 发布:做耳环的材料淘宝店铺 编辑:程序博客网 时间:2024/05/18 04:26

题目分析

求联通块但是R和C很大,用bfs很明显会超时,因此需要对其进行离散化,这一点我在我的前几篇博文中提过,但是本题还涉及到一个新的知识点,离散化之后还需要知道每个连通块中cell的个数,因此还需要一点小技巧,就是利用2个数组存储中间值。

#include <map>#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 505;#define LL long long#define PII pair <int, int>bool vis[maxn][maxn];int R, C, n;int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};int x1[maxn], y1[maxn], x2[maxn], y2[maxn];PII P[maxn];map <int, int> X, Y;LL ans[maxn];void solve(){    scanf("%d%d%d", &R, &C, &n);    int num1 = 0; x1[++num1] = 1; x1[++num1] = R;  //注意边界值要加上,想一想为什么    int num2 = 0; y1[++num2] = 1; y1[++num2] = C;    for(int i = 0; i < n; i++){        scanf("%d%d", &P[i].first, &P[i].second);        x1[++num1] = P[i].first;        y1[++num2] = P[i].second;    }    sort(x1+1, x1+num1+1);    int xnum = unique(x1+1, x1+num1+1) - x1 - 1;    sort(y1+1, y1+num2+1);    int ynum = unique(y1+1, y1+num2+1) - y1 - 1;    X.clear(), Y.clear();    int xx = 0, yy = 0;    for(int i = 1; i <= xnum; i++){        if(x1[i] - x1[i-1] != 1)            x2[++xx] = x1[i] - x1[i-1] - 1;        x2[++xx] = 1;        X[x1[i]] = xx;    }    for(int i = 1; i <= ynum; i++){        if(y1[i] - y1[i-1] != 1)            y2[++yy] = y1[i] - y1[i-1] - 1;        y2[++yy] = 1;        Y[y1[i]] = yy;    }    memset(vis, false, sizeof(vis));    for(int i = 0; i < n; i++) vis[X[P[i].first]][Y[P[i].second]] = true;//    printf("%d, %d\n", X[P[0].first], Y[P[0].second]);    queue <PII> que;    int flag = 0;//    printf("xx = %d, yy = %d\n", xx, yy);    for(int i = 1; i <= xx; i++){        for(int j = 1; j <= yy; j++) if(!vis[i][j]) {            LL cnt = 0;            que.push(make_pair(i, j));            vis[i][j] = true;            while(!que.empty()){                PII cur = que.front(); que.pop();                cnt += (LL)x2[cur.first]*y2[cur.second]; //               printf("x = %d, y = %d\n", x2[cur.first], y2[cur.second]);                for(int k = 0; k < 4; k++){                    int nx = cur.first + dir[k][0];                    int ny = cur.second + dir[k][1];                    if(nx < 1 || nx > xx || ny < 1 || ny > yy || vis[nx][ny]) continue;                    vis[nx][ny] = 1;                    que.push(make_pair(nx, ny));                }            }            ans[flag++] = cnt;        }    }    sort(ans, ans+flag);    printf("%d\n", flag);    for(int i = 0; i < flag; i++){        if(i) printf(" ");        printf("%I64d", ans[i]);    }    printf("\n");}int main(){    int T;    scanf("%d", &T);    for(int kase = 1; kase <= T; kase++){        printf("Case #%d:\n", kase);        solve();    }    return 0;}
0 0
原创粉丝点击