题意:判断两个多边形是否有面积大于0的公共部分

思路:扫描线基础。

#pragma comment(linker, "/STACK:10240000")
#include <bits/stdc++.h>
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)) typedef long long ll;
typedef pair<int, int> pii; namespace Debug {
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;}
}
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);}
/* -------------------------------------------------------------------------------- */ const double eps = 1e-10;/** 设置比较精度 **/
struct Real {
double x;
double get() { return x; }
Real(const double &x) { this->x = x; }
Real() {} Real operator + (const Real &that) const { return Real(x + that.x);}
Real operator - (const Real &that) const { return Real(x - that.x);}
Real operator * (const Real &that) const { return Real(x * that.x);}
Real operator / (const Real &that) const { return Real(x / that.x);} Real operator += (const Real &that) { return Real(x += that.x); }
Real operator -= (const Real &that) { return Real(x -= that.x); }
Real operator *= (const Real &that) { return Real(x *= that.x); }
Real operator /= (const Real &that) { return Real(x /= that.x); } bool operator < (const Real &that) const { return x - that.x <= -eps; }
bool operator > (const Real &that) const { return x - that.x >= eps; }
bool operator == (const Real &that) const { return x - that.x > -eps && x - that.x < eps; }
bool operator <= (const Real &that) const { return x - that.x < eps; }
bool operator >= (const Real &that) const { return x - that.x > -eps; }
}; struct Point {
Real x, y;
int read() { return scanf("%lf%lf", &x.x, &y.x); }
Point(const Real &x, const Real &y) { this->x = x; this->y = y; }
Point() {}
Point operator + (const Point &that) const { return Point(this->x + that.x, this->y + that.y); }
Point operator - (const Point &that) const { return Point(this->x - that.x, this->y - that.y); }
Real operator * (const Point &that) const { return x * that.x + y * that.y; }
Point operator * (const Real &that) const { return Point(x * that, y * that); }
Point operator += (const Point &that) { return Point(this->x += that.x, this->y += that.y); }
Point operator -= (const Point &that) { return Point(this->x -= that.x, this->y -= that.y); }
Point operator *= (const Real &that) { return Point(x *= that, y *= that); }
Real cross(const Point &that) const { return x * that.y - y * that.x; }
};
typedef Point Vector; struct Segment {
Point a, b;
Segment(const Point &a, const Point &b) { this->a = a; this->b = b; }
Segment() {}
bool intersect(const Segment &that) const {
Point c = that.a, d = that.b;
Vector ab = b - a, cd = d - c, ac = c - a, ad = d - a, ca = a - c, cb = b - c;
return ab.cross(ac) * ab.cross(ad) < && cd.cross(ca) * cd.cross(cb) < ;
}
Point getLineIntersection(const Segment &that) const {
Vector u = a - that.a, v = b - a, w = that.b - that.a;
Real t = w.cross(u) / v.cross(w);
return a + v * t;
}
}; Point p1[], p2[];
Segment side1[], side2[]; bool cmp(const pair<Segment, int> &a, const pair<Segment, int> &b) {
return a.X.a.x + a.X.b.x < b.X.a.x + b.X.b.x;
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n, m, cas = ;
while (cin >> n) {
for (int i = ; i < n; i ++) {
p1[i].read();
if (i) side1[i - ] = Segment(p1[i - ], p1[i]);
}
side1[n - ] = Segment(p1[n - ], p1[]);
cin >> m;
for (int i = ; i < m; i ++) {
p2[i].read();
if (i) side2[i - ] = Segment(p2[i - ], p2[i]);
}
side2[m - ] = Segment(p2[m - ], p2[]);
/** 得到所有的扫描线并排序去重 **/
vector<Real> Y;
for (int i = ; i < n; i ++) Y.pb(p1[i].y);
for (int i = ; i < m; i ++) Y.pb(p2[i].y);
for (int i = ; i < n; i ++) {
for (int j = ; j < m; j ++) {
if (side1[i].intersect(side2[j])) {
Y.pb(side1[i].getLineIntersection(side2[j]).y);
}
}
}
sort(all(Y));
Y.resize(unique(all(Y)) - Y.begin());
//Debug::print("Y.size=", Y.size());
Real area = ;
for (int i = ; i < Y.size(); i ++) {
vector<pair<Segment, int> > V;
/** 得到扫描线之间的所有线段 **/
for (int j = ; j < n; j ++) {
Real miny = side1[j].a.y, maxy = side1[j].b.y;
if (miny > maxy) swap(miny, maxy);
if (miny <= Y[i - ] && maxy >= Y[i]) {
Point dot1 = side1[j].getLineIntersection(Segment(Point(, Y[i - ]), Point(, Y[i - ])));
Point dot2 = side1[j].getLineIntersection(Segment(Point(, Y[i]), Point(, Y[i])));
V.pb(mp(Segment(dot1, dot2), ));
}
}
for (int j = ; j < m; j ++) {
Real miny = side2[j].a.y, maxy = side2[j].b.y;
if (miny > maxy) swap(miny, maxy);
if (miny <= Y[i - ] && maxy >= Y[i]) {
Point dot1 = side2[j].getLineIntersection(Segment(Point(, Y[i - ]), Point(, Y[i - ])));
Point dot2 = side2[j].getLineIntersection(Segment(Point(, Y[i]), Point(, Y[i])));
V.pb(mp(Segment(dot1, dot2), ));
}
}
sort(all(V), cmp);
//Debug::print("V.size=", V.size());
/** 从左至右统计 **/
bool in1 = , in2 = ;/** 当前延伸的区域是否在多边形内部 **/
for (int i = ; i < V.size(); i ++) {
if (in1 && in2) area += V[i].X.a.x - V[i - ].X.a.x + V[i].X.b.x - V[i - ].X.b.x;
if (V[i].Y) in2 ^= ;
else in1 ^= ;
}
}
printf("Case %d: %s\n", ++ cas, area > ? "Yes" : "No");
}
return ;
}

[UVA Live 12931 Common Area]扫描线的更多相关文章

  1. UVA 10405 Longest Common Subsequence

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=16&p ...

  2. UVA 10405 Longest Common Subsequence (dp + LCS)

    Problem C: Longest Common Subsequence Sequence 1: Sequence 2: Given two sequences of characters, pri ...

  3. UVA 10405 Longest Common Subsequence --经典DP

    最长公共子序列,经典问题.算是我的DP开场题吧. dp[i][j]表示到s1的i位置,s2的j位置为止,前面最长公共子序列的长度. 状态转移: dp[i][j] = 0                 ...

  4. [UVa OJ] Longest Common Subsequence

    This is the classic LCS problem. Since it only requires you to print the maximum length, the code ca ...

  5. UVA 10522 Height to Area(知三角形三高求面积)

    思路:海伦公式, AC代码: #include<bits/stdc++.h> using namespace std; int main() { int n; scanf("%d ...

  6. 【uva 12219】Common Subexpression Elimination(图论--树+自定义比较器+映射+递归)

    题意:如题,用表达式树来表示一个表达式,且消除公共的部分,即用编号表示.编号 K 定义为表达式第 K 个出现的字符串. 解法:先构造表达式树,给每棵子树用(string,left_son,right_ ...

  7. hdu---(Tell me the area)(几何/三角形面积以及圆面积的一些知识)

    Tell me the area Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. HDU 1798 Tell me the area

    http://acm.hdu.edu.cn/showproblem.php?pid=1798 Problem Description     There are two circles in the ...

  9. HDU 1798 Tell me the area (数学)

    题目链接 Problem Description     There are two circles in the plane (shown in the below picture), there ...

随机推荐

  1. 【论文笔记】YOLOv4: Optimal Speed and Accuracy of Object Detection

    论文地址:https://arxiv.org/abs/2004.10934v1 github地址:https://github.com/AlexeyAB/darknet 摘要: 有很多特征可以提高卷积 ...

  2. 干货!Python中字符串、列表、元祖、字典,集合之间的转换

    一.字符串的转化 1.字符串转换成列表 字符串转换成list 的时候,str可以作为迭代对象,直接放入:也可以使用split对字符串进行切割.然后返回list s = '1a1b1c' print(l ...

  3. synchronized 的实现原理

    加不加 synchronized 有什么区别? synchronized 作为悲观锁,锁住了什么? synchronized 代码块怎么用 前面 3 篇文章讲了 synchronized 的同步方法和 ...

  4. 不论是 Basic Auth 还是 Digest Auth,都会有 Authorization 字段

    GET /dir/index.html HTTP/1.0 Host: localhost Authorization: Digest username="Mufasa", real ...

  5. 异常:NoSuchFieldError: BEST_MATCHING_HANDLER_ATTRIBUTE

    出现的原因 pom 依赖之间不匹配导致 当前的 pom 调整后访问资源成功后面的 pom

  6. poj_2393 Yogurt factory 贪心

    Yogurt factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16669   Accepted: 8176 D ...

  7. 广深小龙-基于unittest、pytest自动化测试框架之demo来学习啦!!!

    基于unittest.pytest自动化测试框架之demo,赶紧用起来,一起学习吧! demo分为两个框架:①pytest    ②unittest demo 中 包含 web.api 自动化测试框架 ...

  8. CSS开发技巧(四):解决flex多行布局的行间距异常、子元素高度拉伸问题

    在使用flex布局时,若出现换行,有两种较为特殊的现象是值得我们研究的: 子元素高度被拉伸,其实际高度大于它的内容高度. 各行子元素之间的行间距过大,甚至我们根本没有给子元素设置margin. 现在我 ...

  9. 记坑: ConfigurationProperties 和 RefreshScope

    为什么80%的码农都做不了架构师?>>>   当使用spring-cloud-config 和 spring-boot-configuration-processor时 使用bean ...

  10. Git 常见问题汇总

    git reabse 合并多个commit git rebase -i HEAD~{NUM} git rebase -i start end 会进入一个指定区间的commit列表 根据提示进行文本编辑 ...