zoukankan      html  css  js  c++  java
  • HDU 5925 离散化

    东北赛的一道二等奖题 当时学长想了一个dfs的解法并且通过了 那时自己也有一个bfs的解法没有拿出来 一直没有机会和时ji间xing来验证对错 昨天和队友谈离散化的时候想到了 于是用当时的思路做了一下

    题意 : 一个 1e9 * 1e9 的棋盘,有 <=200 个格子是黑的,其他都是白的,问所有白色格子构成的四联通块有多大

    因为棋盘规模过大 而黑点是少的 所以想到了离散化 

    一般离散化保证了离散之后 大小相等关系不变

    把普遍的离散化做一下小修改 使相等的点离散化后相等 相邻的点离散化后相邻 有差距的点离散化后缩小差距到1

    会发现 这样对黑点以及边界进行离散化之后 如果一个连通块被黑点包围 由于 相邻的点仍旧相邻 所以这个连通块离散化后 大小形状都不变

    即 离散化之后 相邻点的骨架结构不变

    那么肯定有空间被压缩了 这些被压缩的空间 就是 “有差距的点离散化后缩小差距到1” 这个时候缩小的空间

    我称它为虚化空间 由题意 第一行列和最后一行列不同时有点 可以发现 如果虚化空间存在的话 最多只有一个 所有不存在于黑点包围范围的白点 都连接在一起 或许它们可能因为黑点的半包围结构没有缩小 但是它们一定会连接在一起 形成虚化空间

    这个虚化空间的规模无法直接求出来(很多别的解法都并非用这种方法 而是压缩矩形)  但是我们知道 出去这个虚化空间 剩下的不是黑点就是被黑点包围的大小不变的白点

    那么我们先对xy分别离散化 然后bfs掉虚化空间 剩下的连通块大小都是真实大小 那么虚化空间的size就是n*m-sum(其余联通块) - 黑点个数

    bfs虚化空间或许是一个难点 因为并不知道哪个点连接进了这个虚化出来的连通块 但是由于第一行和最后一行不能同时有点这个设定 可以发现棋盘的四个角一定有一个点在虚化空间里面

    例如 如果第一行和第一列没有点 那么就满足x最小的点和边界的差距大于1 统一缩小到1 则x为1的点可能存在于虚化空间 只要相对的y也被虚化了

    所以 如果一个白点 它的xy不存在黑点拥有 就没有黑点为其支撑骨架 它就会被离散化

    orz  终于 也算是给了当时的自己一个交代...

    然 这个题有一个坑 它没有说给出的x y 的起点是0还是1 

    会发现唯一一个可能有说明意味的第一组样例 如果代入起点是0 是说得过去的 ... 

    但是代入起点是1 也是说得过去的...

    de了一下午bug...摔 

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<map>
    #include<vector>
    #include<iostream>
    #include<iomanip>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define L long long
    L  n , m ;
    L  many ;
    L  x[205];
    L  y[205];
    struct node{
        L  pre;
        L  now;
    }a[205];
    bool cmp(node a, node b){
        return a.pre < b.pre ;
    }
    L  nn ;
    L  mm ;
    bool cmp2(L a, L b){
        return a < b ;
    }
    void lsh1(){
        a[0].pre = -1;
        a[0].now = -1;
        nn = -1;
        for(L  i = 1; i <= many ; i ++ ){
            a[i].pre = x[i];
        }
        a[many+1].pre = n ;
        sort(a+1,a+1+many+1,cmp) ;
        for(L  i = 1; i <= many+1 ; i ++ ){
            if(a[i].pre == a[i-1].pre){
                a[i].now = a[i-1].now ;
            }
            else if(a[i].pre - a[i-1].pre == 1){
                a[i].now = a[i-1].now + 1;
            }
            else {
                a[i].now = a[i-1].now + 2;
            }
            nn = max(nn , a[i].now) ;
        }
        for(L  i = 1; i <= many; i ++ ){
            for(L  j = 1; j <= many ;j ++ ){
                if(x[i] == a[j].pre){
                    x[i] = a[j].now ;
                    break;
                }
            }
        }
    }
    void lsh2(){
        a[0].pre = -1;
        a[0].now = -1;
        mm = -1;
        for(L  i = 1; i <= many ; i ++ ){
            a[i].pre = y[i];
        }
        a[many+1].pre = m ;
        sort(a+1,a+1+many+1,cmp) ;
        for(L  i = 1; i <= many+1; i ++ ){
            if(a[i].pre == a[i-1].pre){
                a[i].now = a[i-1].now ;
            }
            else if(a[i].pre - a[i-1].pre == 1){
                a[i].now = a[i-1].now + 1;
            }
            else {
                a[i].now = a[i-1].now + 2;
            }
            mm = max(mm , a[i].now) ;
        }
        for(L  i = 1; i <= many; i ++ ){
            for(L  j = 1; j <= many+1 ;j ++ ){
                if(y[i] == a[j].pre){
                    y[i] = a[j].now ;
                    break;
                }
            }
        }
    }
    bool vis[500][500] ;
    L ans[500] ;
    bool check(L  x,L  y){
        if(x >= 0 &&x < nn && y >=0 && y < mm){
            if(vis[x][y])return true;
        }
        return false ;
    }
    L  dx[4] = {1,-1,0,0};
    L  dy[4] = {0,0,1,-1};
    L bfs(L  x,L  y){
        queue<L  >que;
        que.push(x);
        que.push(y);
        vis[x][y]=false;
        L res = 1 ;
        while(!que.empty()){
            L  x = que.front();que.pop();
            L  y = que.front();que.pop();
            for(L  i = 0; i < 4; i ++ ){
                L  xx = dx[i] + x;
                L  yy = dy[i] + y;
                if(check(xx,yy)){
                    que.push(xx);
                    que.push(yy);
                    vis[xx][yy]=false ;
                    res ++ ;
                }
            }
        }
        return res ;
    }
    int main(){
        L  t ;
        scanf("%lld",&t);
        L  cas = 1 ;
        while(t-- ){
            scanf("%lld%lld",&n,&m) ;
            scanf("%lld",&many) ;
            bool qsx = false ;
            bool qsy = false ;
            for(L  i = 1; i <= many ; i ++ ){
                scanf("%lld%lld",&x[i],&y[i]) ;
                x[i] -- ;
                y[i] -- ;
                if(x[i] == 0)qsx = true ;
                if(y[i] == 0)qsy = true ;
            }
            memset(vis, true , sizeof(vis)) ;
            lsh1(); lsh2();
            for(L  i = 1; i <= many ; i ++ ){
                vis[x[i]][y[i]] = false ;
            }
            L  cnt = 0;
            L  z ;
            if(qsx){
                if(qsy){
                    z = bfs(nn-1,mm-1);
                }
                else z = bfs(nn-1,0) ;
            }
            else {
                if(qsy){
                    z = bfs(0,mm-1) ;
                }
                else  z = bfs(0,0) ;
            }
            cnt ++ ;
            ans[cnt] = z;
            L sum = many ;
            for(L  i = 0; i < nn ; i ++ ){
                for(L  j = 0; j < mm ; j ++ ){
                    if(vis[i][j]) {
                        L dd = bfs(i,j) ;
                        sum += dd;
                        cnt ++ ;
                        ans[cnt] = dd ;
                    }
                }
            }
            ans[1] = n*m-sum;
            sort(ans+1,ans+1+cnt,cmp2);
            printf("Case #%lld:
    ",cas++);
            printf("%lld
    ",cnt);
            for(int i = 1; i <= cnt ;i ++ ){
                printf("%lld",ans[i]);
                if(i==cnt)printf("
    ");
                else printf(" ");
            }
        }
    }
    

      

  • 相关阅读:
    RFC3489 STUN之客户端所处环境探测流程与部分属性含义说明
    视频直播中用户连麦技术模型与特点分析
    基于网络流量统计与反馈实现边缘机房间媒体流流量调度的一种思路
    基于Flash与window平台本地程序通信实现媒体流发布
    基于Flash ActionScript 实现RTMP发布与播放媒本流
    DirectShow音频采集声音不连续问题分析与解决办法经验总结
    一种高性能与高可用的流媒体系统之媒体流状态管理方法
    复用TCP连接提升流媒体服务器之间流量转发效率
    基于块流协议保证音频优先发送
    LibRTMP优化之调整输出块大小
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/6349018.html
Copyright © 2011-2022 走看看