列表

详情


NC20093. [HNOI2012]三角形覆盖问题

描述

二维平面中,给定N个等腰直角三角形(每个三角形的两条直角边分别平行于坐标轴,斜边从左上到右下)。
我们用三个非负整数( x, y, d)来描述这样一个三角形,三角形三个顶点的坐标   分别为(x, y), (x + d, y)和(x, y + d)。
要求计算这N个三角形所覆盖的总面 积。例如,下图有 3 个三角形,覆盖的总面积为 11.0。
 

输入描述

输入文件第一行为一个正整数N,表示三角形的个数。
接下来的N行每行有用空格隔开的三个非负整数,x, y,d,描述一个三角形的顶点坐标,分别为(x, y), (x + d,y), (x,y+d),其中 x, y, d 满足0 ≤x, y, d ≤1000000。
对于50%的数据,1 ≤N≤500;
100%的数据,1≤N≤10000。

输出描述

仅包含一行,为一个实数S,表示所有三角形所覆盖的总面积,输出恰好保留一位小数。

输入数据保证S ≤ 2^31 。

示例1

输入:

3                                           .
1  1 4
2  0 2
3  2 2

输出:

11.0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 540ms, 内存消耗: 608K, 提交时间: 2021-03-24 02:09:21

#include <bits/stdc++.h>

using namespace std;

const int N = 1e4 + 5;
typedef long long LL;

int n;
struct node {
    int x, y, d;
} a[N];
LL sqr(LL x) { return x < 0ll ? 0ll : x * x; }
bool cmpy(node a, node b) { return a.y < b.y; }
vector<int> ys;
int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i].x >> a[i].y >> a[i].d;
        if (a[i].d == 0) continue;
        ys.push_back(a[i].x), ys.push_back(a[i].x + a[i].d);
    }
    sort(a, a + n, cmpy);
    sort(ys.begin(), ys.end());
    ys.erase(unique(ys.begin(), ys.end()), ys.end());
    LL res = 0;
    for (int i = 1; i < ys.size(); i++) {
        int dn = 0, up = 0;  // upl
        for (int j = 0; j < n; j++) {
            if (a[j].d == 0) continue;
            if (a[j].x <= ys[i - 1] && a[j].x + a[j].d >= ys[i]) {
                if (dn == 0 && up == 0) {
                    dn = a[j].y;
                    up = a[j].y + a[j].d - (ys[i - 1] - a[j].x);
                } else {
                    if (a[j].y > up) {
                        res += 2ll * (up - dn) * (ys[i] - ys[i - 1]) -
                               sqr(ys[i] - ys[i - 1]);
                        dn = a[j].y;
                        up = a[j].y + a[j].d - (ys[i - 1] - a[j].x);
                    } else if (a[j].y + a[j].d - (ys[i - 1] - a[j].x) > up) {
                        res += 2ll * (ys[i] - ys[i - 1]) * (a[j].y - dn);
                        if (a[j].y > up - (ys[i] - ys[i - 1])) {
                            res -= sqr(a[j].y - (up - (ys[i] - ys[i - 1])));
                        }
                        dn = a[j].y;
                        up = a[j].y + a[j].d - (ys[i - 1] - a[j].x);
                    }
                }
            }
        }
        if (up == 0 && dn == 0)
            continue;
        else {
            res +=
                2ll * (up - dn) * (ys[i] - ys[i - 1]) - sqr(ys[i] - ys[i - 1]);
        }
    }
    printf("%.1lf", res / 2.0);
    return 0;
}

上一题