题意:判断两个多边形是否有面积大于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. 常用ElasticSearch 查询语句

    为了演示不同类型的 ElasticSearch 的查询,我们将使用书文档信息的集合(有以下字段:title(标题), authors(作者), summary(摘要), publish_date(发布 ...

  2. radio取值

    假设代码如下: 1) <input type="radio"   name="radio"   id="radio1"  checke ...

  3. sql查询慢 查找

    SELECT creation_time N'语句编译时间' ,last_execution_time N'上次执行时间' ,total_physical_reads N'物理读取总次数' ,tota ...

  4. Java IO基础--File常用操作(递归)

    File中经常会使用递归方法打印属性结构.统计文件夹下文件个数.子文件夹个数以及文件大小,可以作为递归的应用练习. 递归的写法,百度一搜一大堆,这里我使用对javabean方式封装了一下: packa ...

  5. 常用的python开发工具对比

    一名优秀的Python开发人员都有一套好用的Python开发工具,好的开发工具可以使Python开发人员的工作更高效,以下是几款比较好用的Python开发工具,Python开发人员,尤其是初学者,可以 ...

  6. c++使用cin、cout与c中使用scanf、printf进行输入输出的效率问题

    在c++中,我们使用cin和cout进行输入输出会比用scanf和printf更加简洁和方便,但是当程序有大量IO的时候,使用cin和cout进行输入输出会比用scanf和printf更加耗时, 在数 ...

  7. 学习笔记-CTF密码相关

    RSA共模攻击 RSA基本原理 ①  选择两个大的质数p和q,N=pq: ②  根据欧拉函数,求得r=(p-1)(q-1): ③  选一个小于r的整数e,求得e关于模r的模反元素d: ④  将p和q的 ...

  8. java内存模型(JMM)和happens-before

    目录 重排序 Happens-Before 安全发布 初始化安全性 java内存模型(JMM)和happens-before 我们知道java程序是运行在JVM中的,而JVM就是构建在内存上的虚拟机, ...

  9. 一款被大厂选用的 Hexo 博客主题

    首先这是一篇自吹自擂的文章,主题是由多位非前端程序员共同开发,目前经过一年半的迭代已经到达 v1.8.0 版本,并且获得大量认可,甚至某大厂员工已经选用作为内部博客,因此我决定写这篇文章向更多人安利它 ...

  10. Git初始化本地代码及提交到服务器

    2019独角兽企业重金招聘Python工程师标准>>> 1.先安装Git客户端 2.进入需要提交的文件夹目录 3.打开Git Bash,点击右键中的Git Bash 打开git命令窗 ...