uva 11665 Chinese Ink (几何+并查集)
随便给12的找了一道我没做过的几何基础题。这题挺简单的,不过uva上通过率挺低,通过人数也不多。
题意是要求给出的若干多边形组成多少个联通块。做的时候要注意这题是不能用double浮点类型的,然后判多边形交只需要两个条件,存在边规范相交,或者存在一个多边形上的顶点在另一个多边形上或者在多边形内。
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const double EPS = 1e-;
const int N = ;
const int M = ;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);} struct Point {
int x, y;
Point() {}
Point(int x, int y) : x(x), y(y) {}
Point operator + (Point a) { return Point(x + a.x, y + a.y);}
Point operator - (Point a) { return Point(x - a.x, y - a.y);}
Point operator * (int p) { return Point(x * p, y * p);}
Point operator / (int p) { return Point(x / p, y / p);}
} ; inline int cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
inline int dot(Point a, Point b) { return a.x * b.x + a.y * b.y;} inline bool onseg(Point x, Point a, Point b) { return sgn(cross(a - x, b - x)) == && sgn(dot(a - x, b - x)) <= ;}
bool ptinpoly(Point x, Point *pt, int n) {
pt[n] = pt[];
int wn = ;
for (int i = ; i < n; i++) {
if (onseg(x, pt[i], pt[i + ])) return true;
int dr = sgn(cross(pt[i + ] - pt[i], x - pt[i]));
int k1 = sgn(pt[i + ].y - x.y);
int k2 = sgn(pt[i].y - x.y);
if (dr > && k1 > && k2 <= ) wn++;
if (dr < && k2 > && k1 <= ) wn--;
}
return wn != ;
} struct MFS {
int fa[N], cnt;
void init() { for (int i = ; i < N; i++) fa[i] = i; cnt = ;}
int find(int x) { return fa[x] = fa[x] == x ? x : find(fa[x]);}
void merge(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return ;
cnt++;
fa[fx] = fy;
}
} mfs; Point poly[N][M];
char buf[];
int sz[N]; bool ssint(Point a, Point b, Point c, Point d) {
int s1 = sgn(cross(a - c, b - c));
int s2 = sgn(cross(a - d, b - d));
int t1 = sgn(cross(c - a, d - a));
int t2 = sgn(cross(c - b, d - b));
return s1 * s2 < && t1 * t2 < ;
} bool polyint(int a, int b) {
poly[a][sz[a]] = poly[a][];
poly[b][sz[b]] = poly[b][];
for (int i = ; i < sz[a]; i++) {
for (int j = ; j < sz[b]; j++) {
if (ssint(poly[a][i], poly[a][i + ], poly[b][j], poly[b][j + ])) return true;
}
}
return false;
} bool test(int a, int b) {
for (int i = ; i < sz[a]; i++) if (ptinpoly(poly[a][i], poly[b], sz[b])) return true;
for (int i = ; i < sz[b]; i++) if (ptinpoly(poly[b][i], poly[a], sz[a])) return true;
if (polyint(a, b)) return true;
return false;
} int main() {
//freopen("in", "r", stdin);
int n;
while (cin >> n && n) {
gets(buf);
char *p;
mfs.init();
for (int i = ; i < n; i++) {
gets(buf);
p = strtok(buf, " ");
for (sz[i] = ; p; sz[i]++) {
sscanf(p, "%d", &poly[i][sz[i]].x);
p = strtok(NULL, " ");
sscanf(p, "%d", &poly[i][sz[i]].y);
p = strtok(NULL, " ");
}
//cout << sz[i] << endl;
for (int j = ; j < i; j++) if (test(i, j)) {
mfs.merge(i, j);
//cout << i << ' ' << j << endl;
}
}
cout << n - mfs.cnt << endl;
}
return ;
}
——written by Lyon
uva 11665 Chinese Ink (几何+并查集)的更多相关文章
- UVA 572 油田连通块-并查集解决
题意:8个方向如果能够连成一块就算是一个连通块,求一共有几个连通块. 分析:网上的题解一般都是dfs,但是今天发现并查集也可以解决,为了方便我自己理解大神的模板,便尝试解这道题目,没想到过了... # ...
- UVA 12232 - Exclusive-OR(带权并查集)
UVA 12232 - Exclusive-OR 题目链接 题意:有n个数字.一開始值都不知道,每次给定一个操作,I a v表示确认a值为v,I a b v,表示确认a^b = v,Q k a1 a2 ...
- UVA 1160 - X-Plosives 即LA3644 并查集判断是否存在环
X-Plosives A secret service developed a new kind ofexplosive that attain its volatile property only ...
- uva 1493 - Draw a Mess(并查集)
题目链接:uva 1493 - Draw a Mess 题目大意:给定一个矩形范围,有四种上色方式,后面上色回将前面的颜色覆盖,最后问9种颜色各占多少的区域. 解题思路:用并查集维护每一个位置相应下一 ...
- UVA 11987 Almost Union-Find (并查集+删边)
开始给你n个集合,m种操作,初始集合:{1}, {2}, {3}, … , {n} 操作有三种: 1 xx1 yy1 : 合并xx1与yy1两个集合 2 xx1 yy1 :将xx1元素分离出来合到yy ...
- UVA - 1160(简单建模+并查集)
A secret service developed a new kind of explosive that attain its volatile property only when a spe ...
- UVA 1493 Draw a Mess(并查集+set)
这题我一直觉得使用了set这个大杀器就可以很快的过了,但是网上居然有更好的解法,orz... 题意:给你一个最大200行50000列的墙,初始化上面没有颜色,接着在上面可能涂四种类型的形状(填充): ...
- UVa 1455 Kingdom 线段树 并查集
题意: 平面上有\(n\)个点,有一种操作和一种查询: \(road \, A \, B\):在\(a\),\(b\)两点之间加一条边 \(line C\):询问直线\(y=C\)经过的连通分量的个数 ...
- UVA 1329 Corporative Network【并查集】
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
随机推荐
- SQLite in Python: 如何在Python中使用SQLite数据库
SQLite3 可使用 sqlite3 模块与 Python 进行集成.sqlite3 模块是由 Gerhard Haring 编写的.它提供了一个与 PEP 249 描述的 DB-API 2.0 规 ...
- linux交换两个文件的文件名
- ES 6.X的环境搭建
一.ES windows环境下的安装 1.官网下载windows安装包 2.解压启动 F:\software\ES\elasticsearch-6.4.0\bin\elasticsearch 3.查看 ...
- Docker的asp.net core应用部署系列——docker pull 加速
原文:Docker的asp.net core应用部署系列--docker pull 加速 版权声明:本文为博主原创文章,随意转载. https://blog.csdn.net/Michel4Liu/a ...
- Eclipse Jobs 和后台进程
Eclipse后台进程 1.主线程(Main thread) 一个Eclipse客户端只能跑一个进程,但却可以创建很多线程. 在Eclipse框架中,会用一个单线程去运行所有的代码指令,这个线程执行客 ...
- SPARK-SQL内置函数之字符串函数
转载请注明转自:http://www.cnblogs.com/feiyumo/p/8763186.html 1.concat对于字符串进行拼接 concat(str1, str2, ..., strN ...
- 跨域知识(一)——CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
- android 重写系统进度条
转载自http://blog.csdn.net/codingandroid/article/details/8495074 自定义progressbar现在要自定义一个等待的时候转动的小圈,相信大家也 ...
- 预警| Confluence 高危漏洞被大规模利用,阿里云WAF接入即可防护,支持免费应急服务
2019年4月4日,阿里云安全应急响应中心监测到Confluence 官方发布安全更新指出,Widget Connector 存在服务端模板注入漏洞,攻击者能利用此漏洞实现目录穿越遍历甚至远程命令执行 ...
- Hibernate错误——No row with the given identifier exists
错误 是用的是Hibernate自动建立的数据表,在进行数据库操作时,出现错误No row with the given identifier exists 解决 关系数据库一致性遭到了破坏,找到相关 ...