[CQOI2005]三角形面积并

news/2024/7/5 6:25:33

[CQOI2005]三角形面积并

题目大意:

\(n(n\le100)\)个三角形的面积并。

思路:

自适应辛普森法,玄学卡精度可过。

源代码:

#include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
    register char ch;
    while(!isdigit(ch=getchar()));
    register int x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return x;
}
const int N=101;
const double eps=1e-10;
struct Point {
    double x,y;
};
struct Triangle {
    Point p1,p2,p3;
};
Triangle t[N];
struct Node {
    double p;
    int v,id;
    bool operator < (const Node &rhs) const {
        return p<rhs.p;
    }
};
std::vector<Node> v;
std::vector<int> c;
inline bool cross(const Point &a,const Point &b,const double &x) {
    if(a.x==b.x) return false;
    if(a.x<b.x) {
        return a.x<=x&&x<b.x;
    } else {
        return b.x<x&&x<=a.x;
    }
}
inline double calc(const Point &a,const Point &b,const double &x) {
    return (b.y-a.y)/(b.x-a.x)*(x-a.x)+a.y;
}
inline double F(const double &x) {
    std::vector<std::pair<double,int> > v;
    for(register unsigned j=0;j<c.size();j++) {
        const int &i=c[j];
        double q[3];
        int h=0;
        if(cross(t[i].p1,t[i].p2,x)) {
            q[h++]=calc(t[i].p1,t[i].p2,x);
        }
        if(cross(t[i].p2,t[i].p3,x)) {
            q[h++]=calc(t[i].p2,t[i].p3,x);
        }
        if(cross(t[i].p3,t[i].p1,x)) {
            q[h++]=calc(t[i].p3,t[i].p1,x);
        }
        if(h==2) {
            if(q[0]>q[1]) std::swap(q[0],q[1]);
            v.push_back(std::make_pair(q[0],1));
            v.push_back(std::make_pair(q[1],-1));
        }
    }
    std::sort(v.begin(),v.end());
    double st,ans=0;
    for(register unsigned i=0,tmp=0;i<v.size();i++) {
        if(tmp==0) st=v[i].first;
        tmp+=v[i].second;
        if(tmp==0) {
            ans+=v[i].first-st;
        }
    }
    return ans;
}
inline double simpson(const double &fl,const double &fm,const double &fr,const double &len) {
    return (fl+4*fm+fr)*len/6;
}
inline double asr(const double &a,const double &b,const double &fl,const double &fm,const double &fr,const int &d) {
    const double c=(a+b)/2;
    const double flm=F((a+c)/2),frm=F((c+b)/2);
    const double ls=simpson(fl,flm,fm,c-a),rs=simpson(fm,frm,fr,b-c),s=simpson(fl,fm,fr,b-a);
    if(fabs(ls+rs-s)<eps&&d>13) return ls+rs;
    return asr(a,c,fl,flm,fm,d+1)+asr(c,b,fm,frm,fr,d+1);
}
int main() {
    const int n=getint();
    for(register int i=1;i<=n;i++) {
        scanf("%lf%lf%lf%lf%lf%lf",&t[i].p1.x,&t[i].p1.y,&t[i].p2.x,&t[i].p2.y,&t[i].p3.x,&t[i].p3.y);
        v.push_back((Node){std::min(std::min(t[i].p1.x,t[i].p2.x),t[i].p3.x),1,i});
        v.push_back((Node){std::max(std::max(t[i].p1.x,t[i].p2.x),t[i].p3.x),-1,i});
    }
    std::sort(v.begin(),v.end());
    int tmp=0,beg;
    double ans=0;
    for(register unsigned i=0;i<v.size();i++) {
        if(tmp==0) beg=i;
        tmp+=v[i].v;
        if(tmp==0) {
            for(register unsigned j=beg;j<=i;j++) {
                c.push_back(v[j].id);
            }
            std::sort(c.begin(),c.end());
            c.resize(std::unique(c.begin(),c.end())-c.begin());
            const double &st=v[beg].p,&en=v[i].p;
            ans+=asr(st,en,F(st),F((st+en)/2),F(en),1);
            c.clear();
        }
    }
    printf("%.2f\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/skylee03/p/10182995.html


http://www.niftyadmin.cn/n/1774053.html

相关文章

12月自我考核

.执行一条命令&#xff0c;直接添加用户zsh1-zsh20 for s in{1..20};do useradd zsh$s;done转载于:https://blog.51cto.com/13803911/2335807

怎样才能学好Python?

Python是一门简单优雅的计算机程序设计语言&#xff0c;相比于C语言、Java编程&#xff0c;Python无论是从语法结构&#xff0c;还是学习难易程度&#xff0c;更适合0基础人员学习&#xff0c;Python应用领域广阔&#xff0c;从云计算、大数据到人工智能&#xff0c;Python无处…

python_爬取【安居客房源信息】

最近在看房子&#xff0c;试着抓取了安居客上房源信息&#xff0c;供大家学习参考。 #-*- encodingUTF-8 -*- from urllib.request import urlopen from bs4 import BeautifulSoup import xlrd import xlwtcity"sz" ###城市缩写 html_sheet5 ###页面数 url&qu…

readwrite(输入输出流)【模板】

为什么会快 C中getchar的速度是比scanf快很多的 fread其实是输入中最快的 只不过不会用 然后输出自然也是putchar更胜一筹 fwrite也是输出中最快 只不过也不会用 Code&#xff1a; 注释版&#xff1a; #include<cstdio> #include<iostream> #include<algor…

阿里云CDN实时日志服务正式发布,数据驱动,实时决策

12月26日&#xff0c;阿里云CDN实时日志服务举办线上直播发布会&#xff0c;全网首次深度解读阿里云CDN大数据系统技术演进&#xff0c;产品应用场景与业务实操。阿里云CDN实时日志服务可以将CDN采集的实时日志&#xff0c;在小于60秒的时间进行实时、交互式分析和报表呈现&…

python_爬取【proxy ip】

最近在抓取豆瓣电影信息&#xff0c;但是请求太过频繁后&#xff0c;豆瓣后台会封掉请求IP&#xff0c;导致请求403&#xff0c;查了一圈资料&#xff0c;发现可以使用代理IP进行访问&#xff0c;代理IP的获取网址为&#xff1a;http://www.xicidaili.com/ 获取代理IP后&#x…

leetcode 21 合并两个有序的链表

题目描述&#xff1a; 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例&#xff1a; 输入&#xff1a;1->2->4, 1->3->4 输出&#xff1a;1->1->2->3->4->4 思路&#xff1a;先设立一个头结点…

python_常用知识总结

目录 1.操作EXCEL 2.操作TXT 3.爬取网页 4.BeautifulSoup 5.随机数 6.时间类 7.移除列表元素 8.列表排序 9.append&extend 10.优雅访问列表下标索引 11.对字典按照value进行排序 12 自动备份mysql数据库脚本 13 字目和数字转换 14 dict初始化的方法 15 tupl…