zoukankan      html  css  js  c++  java
  • 坐标离散化

       

      

      准备好 w * h 的数组,并记录是否有直线通过,然后利用深度优先搜索可以求出被分割出的区域的个数。但是这个问题中 w 和 h 最大为10000000,所以没办法创建 w * h 的数组。因此我们可以使用坐标离散化这一技巧。

      

      如上图所示,将前后没有变化的行列消除后并不会影响区域的个数。

      数组里只需要存储有直线的行列以及前后的行列就足够了,这样的话最多 6n * 6n 就足够了。

    int W, H, N;
    int X1[MAX_N], X2[MAX_N], Y1[MAX_N], Y2[MAX_N];
    
    bool fld[MAX_N * 6][MAX_N * 6];
    
    //对X1和X2进行坐标离散化,并返回离散化后的宽度
    int compress(int *x1, int x2, int w) {
        vector<int> xs;
        
        for (int i = 0; i < N; i++)
            for (int d = -1; d <= 1; d++) {
                int tx1 = x1[i] + d, tx2 = x2[i] + d;
                if (1 <= tx1 && tx1 <= W) xs.push_back(tx1);
                if (1 <= tx2 && tx2 <= W) xs.push_back(tx2);
            }
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
        
        for (int i = 0; i < N; i++) {
            x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin();
            x1[2] = find(xs.begin(), xs.end(), x2[i]) - xs.begin();
        }
        
        return xs.size();
    } 
    
    void solve() {
        // 坐标离散化
        W = compress(X1, X2, W);
        H = compress(Y1, Y2, H);
        
        // 填充有直线的部分
        memset(fld, 0, sizeof(fld));
        for (int i = 0; i < N; i++)
            for (int y = Y1[i]; y <= Y2[i]; y++)
                for (int x = X1[i]; x <= X2[i]; x++)
                    fld[y][x] = true;
        
        //求区域的个数 
        int ans = 0;
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                if (fld[y][x]) continue;
                ans++;
                
                //宽度优先搜索
                queue<pair<int, int> > q;
                q.push(make_pair(x, y));
                while (!q.empty()) {
                    int sx = q.front().first();
                    int sy = q.front().second();
                    q.pop();
                    
                    for (int i = 0; i < 4; i++) {
                        int tx = sx + dx[i], ty = sy + dy[i];
                        if (tx < 0 || W <= tx || ty < 0 || H <= ty) continue;
                        q.push(make_pair(tx, ty));
                        fld[tx][ty] = true;
                    }
                } 
            }
        }
        printf("%d
    ", ans);
    }
  • 相关阅读:
    [CSS] prefers-reduced-motion
    [VSCode] Adding Custom Syntax Highlighting to a Theme in VSCode
    Subversion/Git/ReviewBoard工作流程
    oracle hints
    Node.js学习(10)----文件系统fs
    网络子系统41_inet_peer平衡二叉树的删除
    由链表初始化看C语言的二级指针
    挣值管理不是搞数字游戏(4)——让挣值管理实用!
    关于数据库一致改关闭下redo日志文件丢失的处理办法的总结
    Android 操作系统的内存回收机制
  • 原文地址:https://www.cnblogs.com/astonc/p/10864317.html
Copyright © 2011-2022 走看看