[UVA Live 12931 Common Area]扫描线
题意:判断两个多边形是否有面积大于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]扫描线的更多相关文章
- UVA 10405 Longest Common Subsequence
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=16&p ...
- UVA 10405 Longest Common Subsequence (dp + LCS)
Problem C: Longest Common Subsequence Sequence 1: Sequence 2: Given two sequences of characters, pri ...
- UVA 10405 Longest Common Subsequence --经典DP
最长公共子序列,经典问题.算是我的DP开场题吧. dp[i][j]表示到s1的i位置,s2的j位置为止,前面最长公共子序列的长度. 状态转移: dp[i][j] = 0 ...
- [UVa OJ] Longest Common Subsequence
This is the classic LCS problem. Since it only requires you to print the maximum length, the code ca ...
- UVA 10522 Height to Area(知三角形三高求面积)
思路:海伦公式, AC代码: #include<bits/stdc++.h> using namespace std; int main() { int n; scanf("%d ...
- 【uva 12219】Common Subexpression Elimination(图论--树+自定义比较器+映射+递归)
题意:如题,用表达式树来表示一个表达式,且消除公共的部分,即用编号表示.编号 K 定义为表达式第 K 个出现的字符串. 解法:先构造表达式树,给每棵子树用(string,left_son,right_ ...
- hdu---(Tell me the area)(几何/三角形面积以及圆面积的一些知识)
Tell me the area Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU 1798 Tell me the area
http://acm.hdu.edu.cn/showproblem.php?pid=1798 Problem Description There are two circles in the ...
- HDU 1798 Tell me the area (数学)
题目链接 Problem Description There are two circles in the plane (shown in the below picture), there ...
随机推荐
- 基础_TCP/IP
概念明确: 1:TCP/IP代表传输控制协议/网际协议,指的是一系列协议 为什么会叫TCP/IP.因为用的多, 2:HTTP 是属于应用层的协议 3:OSI七层模型和TCP/IP 平等,只是TCP/ ...
- mybatis一级缓存让我憔悴
Mybatis对缓存提供支持,是默认开启一级缓存. 来一段代码,这边使用的是mybatis-plus框架,通过构建 QueryWrapper 查询类来实现的. @Transactional publi ...
- notepad++批量每行加字符
移动光标到头 选择正则 输入^ 下面输入需要加的文本. 点替换
- 前端学习笔记-JavaScript
js引入方式: 1.嵌入js的方式:直接在页内的script标签内书写js功能代码. <script type="text/javascript">alert('hel ...
- 开始appium的第一个脚本
设置DesiredCapabilities 存在于以下库中: org.openqa.selenium.remote.DesiredCapabilities Desired Capabilities告诉 ...
- Java实现链表(个人理解链表的小例子)
1.单链表和数组的区别 数组:数组的存储空间是连续的,需要事先申请空间确定大小,通过下标查找数据,所以查找速度快,但是增加和删除速度慢 链表:离散存储,不需要事先确定大小,通过头指针加遍历查找数据,查 ...
- React Hooks: useCallback理解
useCallback把匿名回调“存”起来 避免在component render时候声明匿名方法,因为这些匿名方法会被反复重新声明而无法被多次利用,然后容易造成component反复不必要的渲染. ...
- 深入理解kestrel的应用
1 前言 之所以写本文章,是因为在我停止维护多年前写的NetworkSocket组件两年多来,还是有一些开发者在关注这个项目,我希望有类似需求的开发者明白为什么要停止更新,可以使用什么更好的方式来替换 ...
- pytorch torchversion标准化数据
新旧标准差的关系
- NER命名实体识别,实体级level的评估,精确率、召回率和F1值
pre = "0 0 B_SONG I_SONG I_SONG 0 B_SONG I_SONG I_SONG 0 0 B_SINGER I_SINGER I_SINGER 0 O O O B ...