• [USACO 6.2.3] Shaping Regions


    题目大意

      N个不同颜色矩形放在同一方框内,每个矩形都至少有一部分被看见,求每个矩形被看见的面积.

    题解

      这道题和usaco以前做过的某道题我感觉很类似.

      使用漂浮法,或者说是矩形分割法.

      想象一下,每个矩形有一个层次标记.低层次的会被高层次的覆盖.我们想象一下低层次的矩形向上漂浮,然后撞到了一个矩形.然后这个漂浮ing的矩形就会分割成若干个矩形.然后这若干个矩形继续向上漂浮.直到漂浮到水面上或者说没有比它更高层次的矩形时停下来统计面积即可.

      利用上面所述的漂浮法的思想可以得到O(N2)的算法.

    代码

    /*
    TASK:rect1
    LANG:C++
    */
    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    struct Matrix
    {
        int x1, y1, x2, y2, cr;
    }mat[1005];
    
    int cnt[2505], n;
    
    int floatup(int x1, int y1, int x2, int y2, int k)
    {
        if (x2 < x1 || y2 < y1) return 0;
        if (k == n + 1) return (x2 - x1 + 1) * (y2 - y1 + 1);
        if (x1 > mat[k].x2 || x2 < mat[k].x1 || y1 > mat[k].y2 || y2 < mat[k].y1)
            return floatup(x1, y1, x2, y2, k + 1);
        return floatup(x1, y1, mat[k].x1 - 1, y2, k + 1)
                + floatup(max(x1, mat[k].x1), y1, min(x2, mat[k].x2), mat[k].y1 - 1, k + 1)
                + floatup(max(x1, mat[k].x1), mat[k].y2 + 1, min(x2, mat[k].x2), y2, k + 1)
                + floatup(mat[k].x2 + 1, y1, x2, y2, k + 1);
    }
    
    int main()
    {
        freopen("rect1.in", "r", stdin);
        freopen("rect1.out", "w", stdout);
        mat[0].x1 = mat[0].y1 = 0;
        mat[0].cr = 1;
        scanf("%d%d%d", &mat[0].x2, &mat[0].y2, &n);
        mat[0].x2--;
        mat[0].y2--;
        for (int i = 1; i <= n; ++i)
        {
            scanf("%d%d%d%d%d", &mat[i].x1, &mat[i].y1, &mat[i].x2, &mat[i].y2, &mat[i].cr);
            mat[i].x1 = max(mat[i].x1, mat[0].x1);
            mat[i].y1 = max(mat[i].y1, mat[0].y1);
            mat[i].x2 = min(mat[i].x2-1, mat[0].x2);
            mat[i].y2 = min(mat[i].y2-1, mat[0].y2);
        }
        memset(cnt, 0, sizeof(cnt));
        cnt[mat[n].cr] = (mat[n].x2 - mat[n].x1 + 1) * (mat[n].y2 - mat[n].y1 + 1);
        for (int i = n-1; i >= 0; --i)
            cnt[mat[i].cr] += floatup(mat[i].x1, mat[i].y1, mat[i].x2, mat[i].y2, i + 1);
        for (int i = 1; i <= 2500; ++i)
            if (cnt[i]) printf("%d %d
    ", i, cnt[i]);
        return 0;
    }
  • 相关阅读:
    Android获取手机内存和sd卡相关信息
    总结(创建快捷方式等)
    正则是个好东西
    Android自定义AlertDialog
    Eclipse生成author等注释
    day18 io多路复用
    json 模块
    re 模块
    random 模块
    hashlib 模块
  • 原文地址:https://www.cnblogs.com/albert7xie/p/5732969.html
Copyright © 2020-2023  润新知