[CODEVS 3044] 矩形面积求并

描述

输入n个矩形,求他们总共占地面积(也就是求一下面积的并)
http://codevs.cn/problem/3044/


分析

先贴个Matrix67的讲离散化的博客地址: http://www.matrix67.com/blog/archives/108
其实上面的博客讲的讲的就很清楚了.

就相当于把矩形用许多小矩形来代替. 这些小矩形都是有一边或几条边延长后过其他矩形的顶点. 这么一说好像更复杂了. 换个说法, 就是把所有矩形的边都作为可无限延长的分割线, 将所有矩形分割成小矩形. 每个小矩形作为一个新的点, 然后在bool数组里记录哪个点被覆盖, 可以通过预处理或者临时计算出小矩形的面积. 最后扫一遍统计结果.


代码

49ms 256kB

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 100 + 10; 

struct Matrix {
    double x1, y1, x2, y2;
} matrixs[maxn];

double x[maxn<<1], y[maxn<<1];
bool covered[maxn<<1][maxn<<1];

int main() {
    int n;
    while(scanf("%d", &n) == 1) {
        if(n == 0) break;
        for(int i = 0; i < n; i++) {
            double x1, y1, x2, y2;
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            matrixs[i] = (Matrix) {x1, y1, x2, y2};
            x[i<<1] = x1;
            y[i<<1] = y1;
            x[(i<<1) ^ 1] = x2;
            y[(i<<1) ^ 1] = y2;
        }
        sort(x, x + 2*n);
        sort(y, y + 2*n);

        // 以左下点的坐标作为格子的编号.
        memset(covered, 0, sizeof(covered));
        for(int cur = 0; cur < n; cur++) {
            int s_x, s_y, t_x, t_y;
            Matrix& M = matrixs[cur];
            for(s_x = 0; x[s_x] < M.x1; s_x++);
            for(s_y = 0; y[s_y] < M.y1; s_y++);
            for(t_x = s_x; x[t_x] < M.x2; t_x++);
            for(t_y = s_y; y[t_y] < M.y2; t_y++);
            // cover
            for(int i = s_x; i < t_x; i++)
                for(int j = s_y; j < t_y; j++)
                    covered[i][j] = 1;
        }

        double ans = 0.00;
        for(int i = 0; i < 2*n - 1; i++)
            for(int j = 0; j < 2*n - 1; j++)
                if(covered[i][j]) ans += (x[i + 1]-x[i]) * (y[j + 1]-y[j]);
        printf("%.2lf\n", ans);
    }
    return 0;
}

主页

http://blog.csdn.net/qq_21110267

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值