POJ 2284 That Nice Euler Circuit (LA 3263 HDU 1665)
http://poj.org/problem?id=2284
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1264
http://acm.hdu.edu.cn/showproblem.php?pid=1665
题目大意:
平面上有一个包含n个端点的一笔画,第n个端点总是和第一个端点重合,因此图案是一条闭合的曲线。组成一笔画的线段可以相交,但是不会重合。求这些线段将平面分成多少部分。

思路:
刘汝佳书上原题。我基本抄他的,几何题没经验T T。还学到了unique的用法,去除相邻相同的元素
欧拉定理有:设平面图的顶点数、边数、面数分别V,E,F则V+F-E=2(上个学期刚学的离散数学,现学现卖啊!)
如上面的图,右边的E=12,V=9,F=5.
平面图的结点由两部分组成,即原来顶点和新增加的顶点,因为可能出现三点共线,所以要删除重复点。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=300+10;
const double eps = 1e-10;
int dcmp(double x) //判断浮点数是否等于0,或者小于大于0
{
if(fabs(x) < eps)
return 0;
else
return x < 0 ? -1 : 1;
}
struct Point
{
double x, y;
Point(double x=0, double y=0):x(x),y(y) { } };
typedef Point Vector;
Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (const Vector& A, double p) { return Vector(A.x*p, A.y*p); }
double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; }
double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; } //两直线交点,参数式。
Point GetLineIntersection(const Point& P, const Vector& v, const Point& Q, const Vector& w) {
Vector u = P-Q;
double t = Cross(w, u) / Cross(v, w);
return P+v*t;
}
//两直线是否有交点,两点式。
bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
//点在线段上的判定,两点式
bool OnSegment(const Point& p, const Point& a1, const Point& a2) {
return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
} bool operator <(const Point &a,const Point &b)
{
return a.x<b.x||a.x==b.x && a.y<b.y;
}
bool operator ==(const Point &a,const Point &b)
{
return a.x==b.x && a.y==b.y;
}
Point v[MAXN*MAXN],p[MAXN];
int main()
{
int n,kase=1;
while(~scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
v[i]=p[i];
} int len=n--,e=n;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
if(SegmentProperIntersection(p[i],p[i+1],p[j],p[j+1]))
v[len++]=GetLineIntersection(p[i],p[i+1]-p[i],p[j],p[j+1]-p[j]);
} sort(v,v+len);
int c=unique(v,v+len)-v; //去除重复的点
for(int i=0;i<c;i++)
for(int j=0;j<n;j++)
if(OnSegment(v[i],p[j],p[j+1])) e++; //v+f-e=2 f=e+2-v
printf("Case %d: There are %d pieces.\n",kase++,e+2-c);
}
return 0;
}
POJ 2284 That Nice Euler Circuit (LA 3263 HDU 1665)的更多相关文章
- poj 2284 That Nice Euler Circuit 解题报告
That Nice Euler Circuit Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 1975 Accepted ...
- ●POJ 2284 That Nice Euler Circuit
题链: http://poj.org/problem?id=2284 题解: 计算几何,平面图的欧拉定理 欧拉定理:设平面图的定点数为v,边数为e,面数为f,则有 v+f-e=2 即 f=e-v+2 ...
- pku 2284 That Nice Euler Circuit
题意: 给你n个点第n个点保证与第0个点相交,然后求这n个点组成的图形可以把整个平面分成几个面 思路: 这里的解题关键是知道关于多面体的欧拉定理 多面体: 设v为顶点数,e为棱数,f是面数,则v-e+ ...
- That Nice Euler Circuit UVALive - 3263 || 欧拉公式
欧拉定理: 简单多面体的顶点数V.棱数E及面数F间有关系有著名的欧拉公式:V-E+F=2. 设G为任意的连通的平面图,则v-e+f=2,v是G的顶点数,e是G的边数,f是G的面数.(引) 证明(?) ...
- LA 3263 That Nice Euler Circuit(欧拉定理)
That Nice Euler Circuit Little Joey invented a scrabble machine that he called Euler, after the grea ...
- UVALive - 3263 That Nice Euler Circuit (几何)
UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址: UVALive - 3263 That Nice Euler Circuit 题意: 给 ...
- UVALi 3263 That Nice Euler Circuit(几何)
That Nice Euler Circuit [题目链接]That Nice Euler Circuit [题目类型]几何 &题解: 蓝书P260 要用欧拉定理:V+F=E+2 V是顶点数; ...
- poj2284 That Nice Euler Circuit(欧拉公式)
题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k( ...
- POJ2284 That Nice Euler Circuit (欧拉公式)(计算几何 线段相交问题)
That Nice Euler Circuit Time Limit: 3000MS M ...
随机推荐
- 洛谷 P2684 搞清洁
P2684 搞清洁 题目描述 FJ准备分配它的N只奶牛(1 <= N <= 25,000) 做清洁工作,他把一天分成T(1 <= T <= 1,000,000)个时间段,他希望 ...
- 机房收费系统——UML类图
在对一个软件系统进行设计和建模的时候,一般是从构造系统的基本词汇開始,包含构造这些词汇的基本属性和行为. 系统分析师假设要对所设计的系统清晰认识.还有考虑这些基本词汇之间的关系.而假设把这些行为可视化 ...
- 数据库SQL Server2012笔记(四)——多表查询、子查询、分页查询、用查询结果创建新表和外连接
1.多表查询 1)笛卡尔集: select * from 表名1,表名2 select * from 表名1.表名2 where 表名1.字段名=表名2.字段名 注: 若有两张表有同 ...
- hadoop实验:求气象数据的最低温度
1.下载部分数据.由于实验就仅仅下载2003年的部分气象数据 2.通过zcat *gz > sample.txt命令解压重定向 [hadoop@Master test_data]$ zcat * ...
- android图像处理系列之四-- 给图片添加边框(上)
图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下 ...
- JS --- 延迟加载的几种方式
标题:JS延迟加载,也就是等页面加载完成之后再加载 JavaScript 文件. JS延迟加载有助于提高页面加载速度. 1. defer 属性 HTML 4.01 为 <script>标 ...
- Kinect 开发 —— 手势识别(上)
像点击(clicks)是GUI平台的核心,轻点(taps)是触摸平台的核心那样,手势(gestures)是Kinect应用程序的核心 关于手势的定义的中心在于手势能够用来交流,手势的意义在于讲述而不是 ...
- 【Django】缓存
由于Django是动态网站,所以每次请求都会去数据库中进行响应的操作. 当程序访问量大时,耗时必然会更加明显,最简单的解决方案就是使用缓存. Django中的缓存: ==即将某一个view的返回值保存 ...
- buffer--cache 详解
- 小米开源文件管理器MiCodeFileExplorer-源码研究(7)-Favorite收藏管理和SQLite数据库CRUD
FavoriteDatabaseHelper,存储favorite数据,到SQLite数据库.SQLiteOpenHelper是一个帮助管理数据库和版本的工具类.通过继承并重载方法,快速实现了我们自己 ...