题意:给n个三角形,分别求覆盖1次~n次的总面积

思路: 对每个y坐标作一条平行于x轴的直线,按直线从下往上处理,每两条直线之间为若干梯形(也可以是三角形)首尾相连的情况,从左扫到右时,用一个变量cnt记录当前区域被覆盖的次数,遇到入边cnt++,遇到出边cnt--,边扫边更新答案。入边表示这条边的右边在三角形内部,出边表示这条边的右边在三角形的外部。思路并不复杂,只是代码稍长点。

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; //#ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
//#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
template<typename T>
void V2A(T a[],const vector<T>&b){for(int i=;i<b.size();i++)a[i]=b[i];}
template<typename T>
void A2V(vector<T>&a,const T b[]){for(int i=;i<a.size();i++)a[i]=b[i];} const double PI = acos(-1.0);
const int INF = 1e9 + ;
const double EPS = 1e-8; /* -------------------------------------------------------------------------------- */ const int maxn = ; int dcmp(double a) {
if (abs(a) < EPS) return ;
return a > ? : -;
} struct Point {
double x, y;
void read() {
int x, y;
scanf("%d%d", &x, &y);
this->x = x;
this->y = y;
}
Point(double x, double y) {
this->x = x;
this->y = y;
}
Point() {}
Point operator - (const Point &that) const {
return Point(this->x - that.x, this->y - that.y);
}
bool operator < (const Point &that) const {
return dcmp(this->y - that.y) < || dcmp(this->y - that.y) == &&
dcmp(this->x - that.x) < ;
}
Point operator * (const double &m) const {
return Point(this->x * m, this->y * m);
}
};
struct Segment {
Point a, b;
Segment(Point a, Point b) {
this->a = a;
this->b = b;
}
Segment() {}
bool operator < (const Segment &that) const {
return dcmp(this->a.x + this->b.x - that.a.x - that.b.x) < ;
}
};
Point point[maxn * maxn * ];
Segment seg[maxn * ];
int type[maxn * ];
double ans[maxn]; double cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
} bool onMid(Point a, Point b, Point c) {
return dcmp(cross(c - a, b - a)) == ;
}
bool onLeft(Point a, Point b, Point c) {
return dcmp(cross(c - a, b - a)) < ;
}
bool Intersect(Segment A, Segment B) {
int r1 = dcmp(cross(A.b - A.a, B.a - A.a));
int r2 = dcmp(cross(A.b - A.a, B.b - A.a));
int r3 = dcmp(cross(B.b - B.a, A.a - B.a));
int r4 = dcmp(cross(B.b - B.a, A.b - B.a));
return (r1 ^ r2) || (r3 ^ r4);
}
Point getLineIntersection(Segment A, Segment B) {
Point u = A.a - B.a, v = A.b - A.a, w = B.b - B.a;
double t = cross(w, u) / cross(v, w);
return A.a - v * -t;
}
double Area(Segment A, Segment B) {
return fabs((A.a.x - B.a.x + A.b.x - B.b.x) * (A.a.y - A.b.y) / );
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int T, n, cs, cp;
cin >> T;
while (T --) {
cin >> n;
cp = cs = ;
for (int i = ; i < n; i ++) {
Point p[];
for (int j = ; j < ; j ++) p[j].read();
if (onMid(p[], p[], p[])) continue;
sort(p, p + );
seg[cs ++] = Segment(p[], p[]);
seg[cs ++] = Segment(p[], p[]);
seg[cs ++] = Segment(p[], p[]);
if (onLeft(p[], p[], p[])) {
type[cs - ] = type[cs - ] = ;
type[cs - ] = -;
}
else {
type[cs - ] = type[cs - ] = -;
type[cs - ] = ;
}
}
for (int i = ; i < cs; i ++) {
for (int j = i + ; j < cs; j ++) {
if (Intersect(seg[i], seg[j]))
point[cp ++] = getLineIntersection(seg[i], seg[j]);
}
}
sort(point, point + cp);
vector<double> Y;
for (int i = ; i < cp; i ++) {
if (!i || dcmp(point[i].y - point[i - ].y) != ) Y.pb(point[i].y);
}
fillchar(ans, );
for (int i = ; i < Y.size(); i ++) {
vector<pair<Segment, int> > S;
for (int j = ; j < cs; j ++) {
if (dcmp(seg[j].a.y - Y[i - ]) <= && dcmp(seg[j].b.y - Y[i]) >= ) {
Point a = seg[j].a, b = seg[j].b;
double d = (b.x - a.x) / (b.y - a.y);
double x1 = a.x + d * (Y[i - ] - a.y), x2 = a.x + d * (Y[i] - a.y);
S.pb(mp(Segment(Point(x1, Y[i - ]), Point(x2, Y[i])), type[j]));
}
}
sort(all(S));
int cnt = ;
for (int j = ; j < S.size(); j ++) {
if (cnt) ans[cnt] += Area(S[j - ].X, S[j].X);
cnt += S[j].Y;
}
}
for (int i = ; i <= n; i ++) {
printf("%.10f\n", ans[i]);
}
} return ;
}

[hdu4629 Burning]三角形面积并,扫描线的更多相关文章

  1. bzoj 1845: [Cqoi2005] 三角形面积并 扫描线

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 848  Solved: 206[Submit][Statu ...

  2. BZOJ1845 [Cqoi2005] 三角形面积并 扫描线 计算几何

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1845 题意概括 给出n个三角形,求其面积并. 题解 有一个很经典的扫描线题目:矩形面积并.那个比较 ...

  3. BZOJ 1845: [Cqoi2005] 三角形面积并 [计算几何 扫描线]

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1151  Solved: 313[Submit][Stat ...

  4. 【BZOJ1845】[Cqoi2005] 三角形面积并 几何+扫描线

    [BZOJ1845][Cqoi2005] 三角形面积并 Description 给出n个三角形,求它们并的面积. Input 第一行为n(N < = 100), 即三角形的个数 以下n行,每行6 ...

  5. CQOI2005 三角形面积并 和 POJ1177 Picture

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1664  Solved: 443[Submit][Stat ...

  6. ytu 1058: 三角形面积(带参的宏 练习)

    1058: 三角形面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 190  Solved: 128[Submit][Status][Web Boar ...

  7. UVa 11437:Triangle Fun(计算几何综合应用,求直线交点,向量运算,求三角形面积)

    Problem ATriangle Fun Input: Standard Input Output: Standard Output In the picture below you can see ...

  8. OpenJudge计算概论-计算三角形面积【海伦公式】

    /*============================================== 计算三角形面积 总时间限制: 1000ms 内存限制: 65536kB 描述 平面上有一个三角形,它的 ...

  9. nyoj 67 三角形面积【三角形面积公式】

    三角形面积 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 给你三个点,表示一个三角形的三个顶点,现你的任务是求出该三角形的面积   输入 每行是一组测试数据,有6个 ...

随机推荐

  1. [linux][mysql] MySQL中information_schema是什么

    来源:MySQL中information_schema是什么 information_schema数据库是MySQL自带的,information_schema提供了访问数据库元数据的方式.这就是?元 ...

  2. 【题解】P2480 [SDOI2010]古代猪文 - 卢卡斯定理 - 中国剩余定理

    P2480 [SDOI2010]古代猪文 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 猪王国的文明源远流长,博大精 ...

  3. 使用binlog2sql工具来恢复数据库

    (一)binlog2sql介绍 binlog2sql是国内MySQL大佬danfengcao开发,许多MySQL爱好者参与改进的一款MySQL binlog解析软件.根据不同选项,可以得到原始SQL. ...

  4. 如何用Github钩子做自动部署

    最近机缘巧合的购置了域名和服务器,不用实在是浪费,再加上一直没有属于自己的个人网站,所以打算用hexo在服务器上玩一下,这样也就不用再纠结用Github pages还是Gitee pages了.当然, ...

  5. 算法笔记刷题3(codeup 5901)

    今天刷题的速度依旧很慢(小乌龟挥爪.jpg) 我觉得codeup5901中回文串的处理很妙,如果是我自己写的话可能会把数组直接倒过来和原来对比.按照对称规律进行比对的话,工作量可以减少一半. #inc ...

  6. 2019-2020-1 20199310《Linux内核原理与分析》第七周作业

    1.问题描述 在前面的文章中,学习了系统调用system_call的处理过程,在MenuOS中运行getpid命令,通过gdb跟踪调用time函数的过程,并分析system_call代码对应的工作过程 ...

  7. redis部署与卸载

    1.先到Redis官网(redis.io)下载redis安装包 cd /tmp wget http://download.redis.io/releases/redis-4.0.10.tar.gz 2 ...

  8. VulnHub靶场学习_HA: Chanakya

    HA-Chanakya Vulnhub靶场 下载地址:https://www.vulnhub.com/entry/ha-chanakya,395/ 背景: 摧毁王国的策划者又回来了,这次他创造了一个难 ...

  9. asp.net下载大文件代码

    public void Down(string filepath, HttpResponse aResponse) { System.IO.Stream iStream = null; // Buff ...

  10. php数组存在重复的相反元素,去重复

    $arr1=array('a_b','c_d','b_a','d_c'); $arr2=array('a_b','c_d','b_a','d_c'); 条件: a_b==b_a:c_d==d_c: 需 ...