AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 校园
  • 应用
  • 文章
    • 题解
    • 分享
    • 问答
  • 吐槽
  • 登录/注册

AcWing 2801. 三角形面积并    原题链接    困难

作者: 作者的头像   RainSure ,  2022-06-24 11:50:43 ,  所有人可见 ,  阅读 14


2


难写呀 一道题写好久

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 110;
#define x first
#define y second
typedef pair<double, double> PDD;
const double eps = 1e-8;
const double pi = acos(-1);
const double inf = 1e12;
PDD tr[maxn][3];
PDD q[maxn];
int n;
int sign(double x)
{
    if(fabs(x) < eps) return 0;
    if(x < 0) return -1;
    return 1;
}
int dcmp(double x, double y)
{
    if(fabs(x - y) < eps) return 0;
    if(x < y) return -1;
    return 1;
}
PDD operator + (PDD a, PDD b)
{
    return {a.x + b.x, a.y + b.y};
}
PDD operator - (PDD a, PDD b)
{
    return {a.x - b.x, a.y - b.y};
}
PDD operator * (PDD a, double t)
{
    return {a.x * t, a.y * t};
}
PDD operator / (PDD a, double t)
{
    return {a.x / t, a.y / t};
}
double operator * (PDD a, PDD b)
{
    return a.x * b.y - a.y * b.x;
}
double operator & (PDD a, PDD b)
{
    return a.x * b.x + a.y * b.y;
}
bool on_segment(PDD p, PDD a, PDD b)
{
    return sign((p - a) & (p - b)) <= 0;
}
PDD get_line_intersection(PDD p, PDD v, PDD q, PDD w)
{
    if(!sign(v * w)) return {inf, inf};
    auto u = p - q;
    double t = w * u / (v * w);
    auto o = p + v * t;
    if(!on_segment(o, p, p + v) || !on_segment(o, q, q + w)) return {inf, inf};
    return o;
}
double line_range(double a, int side)
{
    int cnt = 0;
    for(int i = 0; i < n; i ++){
        auto t = tr[i];
        if(dcmp(t[0].x, a) > 0 || dcmp(t[2].x, a) < 0) continue;
        if(!dcmp(t[0].x, a) && !dcmp(t[1].x, a)){
            if(side){
                q[cnt ++] = {t[0].y ,t[1].y};
            }
        }
        else if(!dcmp(t[2].x, a) && !dcmp(t[1].x, a)){
            if(!side){
                q[cnt ++] = {t[2].y, t[1].y};
            }
        }else{
            double d[3];
            int u = 0;
            for(int j = 0; j < 3; j ++){
                auto o = get_line_intersection(t[j], t[(j + 1) % 3] - t[j], {a, -inf}, {0, inf * 2});
                if(dcmp(o.x, inf)) d[u ++] = o.y;
            }
            if(u){
                sort(d, d + u);
                q[cnt ++] = {d[0], d[u - 1]};
            }
        }
    }
    if(!cnt) return 0;
    for(int i = 0; i < cnt; i ++){
        if(q[i].x > q[i].y) swap(q[i].x, q[i].y);
    }
    sort(q, q + cnt);
    double res = 0, st = q[0].x, ed = q[0].y;
    for(int i = 1; i < cnt; i ++){
        if(q[i].x <= ed) ed = max(ed, q[i].y);
        else
        {
            res += ed - st;
            st = q[i].x, ed = q[i].y;
        }
    }
    res += ed - st;
    return res;
}
double range_area(double a, double b)
{
    return (line_range(a, 1) + line_range(b, 0)) * (b - a) / 2;
}
int main()
{
    cin >> n;
    vector<double> v;
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < 3; j ++){
            cin >> tr[i][j].x >> tr[i][j].y;
            v.push_back(tr[i][j].x);
        }
        sort(tr[i], tr[i] + 3);
    }
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < n; j ++){
            for(int x = 0; x < 3; x ++){
                for(int y = 0; y < 3; y ++){
                    auto o = get_line_intersection(tr[i][x], tr[i][(x + 1) % 3] - tr[i][x],
                                        tr[j][y], tr[j][(y + 1) % 3] - tr[j][y]);
                    if(dcmp(o.x, inf)) v.push_back(o.x);
                }
            }
        }
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    double res = 0;
    for(int i = 0; i < v.size() - 1; i ++){
        res += range_area(v[i], v[i + 1]);
    }
    printf("%.2lf\n", res);
    return 0;
}

0 评论

你确定删除吗?

© 2018-2022 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息