poj 2284 That Nice Euler Circuit 解题报告
|
That Nice Euler Circuit
Description Little Joey invented a scrabble machine that he called Euler, after the great mathematician. In his primary school Joey heard about the nice story of how Euler started the study about graphs. The problem in that story was - let me remind you - to draw a graph on a paper without lifting your pen, and finally return to the original position. Euler proved that you could do this if and only if the (planar) graph you created has the following two properties: (1) The graph is connected; and (2) Every vertex in the graph has even degree.
Joey's Euler machine works exactly like this. The device consists of a pencil touching the paper, and a control center issuing a sequence of instructions. The paper can be viewed as the infinite two-dimensional plane; that means you do not need to worry about if the pencil will ever go off the boundary. In the beginning, the Euler machine will issue an instruction of the form (X0, Y0) which moves the pencil to some starting position (X0, Y0). Each subsequent instruction is also of the form (X', Y'), which means to move the pencil from the previous position to the new position (X', Y'), thus draw a line segment on the paper. You can be sure that the new position is different from the previous position for each instruction. At last, the Euler machine will always issue an instruction that move the pencil back to the starting position (X0, Y0). In addition, the Euler machine will definitely not draw any lines that overlay other lines already drawn. However, the lines may intersect. After all the instructions are issued, there will be a nice picture on Joey's paper. You see, since the pencil is never lifted from the paper, the picture can be viewed as an Euler circuit. Your job is to count how many pieces (connected areas) are created on the paper by those lines drawn by Euler. Input There are no more than 25 test cases. Ease case starts with a line containing an integer N >= 4, which is the number of instructions in the test case. The following N pairs of integers give the instructions and appear on a single line separated by single spaces. The first pair is the first instruction that gives the coordinates of the starting position. You may assume there are no more than 300 instructions in each test case, and all the integer coordinates are in the range (-300, 300). The input is terminated when N is 0.
Output For each test case there will be one output line in the format
Case x: There are w pieces., where x is the serial number starting from 1. Note: The figures below illustrate the two sample input cases. Sample Input 5 Sample Output Case 1: There are 2 pieces. Source |
[Submit] [Go Back] [Status] [Discuss]
————————————————————我是分割线————————————————————————
绝世好题。
大体思路简单,细节能烦死人。
改了2天,看着题解才写出几个函数。55555........
本题根据平面图的欧拉定理求解区域个数r。
顶点个数:两两线段求交点,每个交点都是图中的顶点。
边数:在求交点时判断每个交点落在几条边上,若一个交点落在某条边上,则将这条边分裂成两条边,边数++。
之后运用欧拉定理求区域个数即可。
最后减的时候,把n处理成了点数,错的离谱......
/*
Problem:poj 2284
OJ: POJ
User: S.B.S.
Time: 454 ms
Memory: 3548 kb
Length: 2643 b
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<iomanip>
#include<cassert>
#include<climits>
#include<vector>
#include<list>
#include<map>
#define maxn 90001
#define F(i,j,k) for(int i=j;i<k;i++)
#define M(a,b) memset(a,b,sizeof(a))
#define FF(i,j,k) for(int i=j;i>=k;i--)
#define inf 0x7fffffff
#define maxm 2016
#define mod 1000000007
#define eps 1e-10
//#define LOCAL
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m;
struct POINT //点
{
double x;
double y;
POINT(double a=,double b=){x=a;y=b;}
};
struct EDGE //线段
{
POINT u;
POINT v;
EDGE(POINT A,POINT B) {u=A;v=B;}
};
struct LINE //直线
{
double a;
double b;
double c;
};
bool operator < (POINT A,POINT B)
{
return A.x<B.x || A.x==B.x && A.y<B.y;
}
bool operator == (POINT a,POINT b)
{
return abs(a.x-b.x)<eps && abs(a.y-b.y)<eps;
}
bool online(EDGE a,POINT b)
{
return abs((a.v.x-a.u.x)*(b.y-a.u.y)-(b.x-a.u.x)*(a.v.y-a.u.y))<eps && (b.x-a.u.x)*(b.x-a.v.x)<eps && (b.y-a.u.y)*(b.y-a.v.y)<eps;
}
LINE makeline(POINT a,POINT b)
{//将线段延长成直线
LINE l;
l.a=(b.y>a.y) ? b.y-a.y : a.y-b.y; //y方向差值
l.b=(b.y>a.y) ? a.x-b.x : b.x-a.x; //x方向差值
l.c=(b.y>a.y) ? a.y*b.x-a.x*b.y : a.x*b.y-a.y*b.x;//与水平线夹角
return l; //返回直线
}
bool lcross(LINE a,LINE b,POINT &p)
{//判断直线是否相交
double d=a.a*b.b-b.a*a.b;
if(abs(d)<eps) return false;
//求交点
p.x=(b.c*a.b-a.c*b.b)/d;
p.y=(b.a*a.c-a.a*b.c)/d;
return true;
}
bool ecross(EDGE a,EDGE b,POINT &p)
{
LINE l1,l2;
l1=makeline(a.u,a.v);
l2=makeline(b.u,b.v);
if(lcross(l1,l2,p)) return online(a,p) && online(b,p);
else return false;
}
POINT p[maxn],in[maxn];
int cur,cnt,ans;
int main()
{
std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
int t=;
while(cin>>n&&n)
{
t++;m=cur=;
for(int i=;i<n;i++) cin>>p[i].x>>p[i].y;
for(int i=;i<n;i++)
for(int j=;j<n;j++){
EDGE l1(p[i],p[(i+)%n]),l2(p[j],p[(j+)%n]);
POINT pp;
if(ecross(l1,l2,pp)) in[cur++]=pp;
}
sort(in,in+cur);
cur=unique(in,in+cur)-in;
for(int i=;i<cur;i++)
for(int j=;j<n;j++){
EDGE ll(p[j],p[(j+)%n]);
if(online(ll,in[i]) && !(ll.u==in[i])) m++;
}
cout<<"Case "<<t<<": There are "<<+m-cur<<" pieces."<<endl;
}
return ;
}
poj 2284
poj 2284 That Nice Euler Circuit 解题报告的更多相关文章
- ●POJ 2284 That Nice Euler Circuit
题链: http://poj.org/problem?id=2284 题解: 计算几何,平面图的欧拉定理 欧拉定理:设平面图的定点数为v,边数为e,面数为f,则有 v+f-e=2 即 f=e-v+2 ...
- 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&a ...
- pku 2284 That Nice Euler Circuit
题意: 给你n个点第n个点保证与第0个点相交,然后求这n个点组成的图形可以把整个平面分成几个面 思路: 这里的解题关键是知道关于多面体的欧拉定理 多面体: 设v为顶点数,e为棱数,f是面数,则v-e+ ...
- poj 1094 Sorting It All Out 解题报告
题目链接:http://poj.org/problem?id=1094 题目意思:给出 n 个待排序的字母 和 m 种关系,问需要读到第 几 行可以确定这些字母的排列顺序或者有矛盾的地方,又或者虽然具 ...
- Poj 1953 World Cup Noise之解题报告
World Cup Noise Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16369 Accepted: 8095 ...
- Poj 2081 Recaman's Sequence之解题报告
...
- POJ 1308 Is It A Tree? 解题报告
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 32052 Accepted: 10876 D ...
- POJ 1958 Strange Towers of Hanoi 解题报告
Strange Towers of Hanoi 大体意思是要求\(n\)盘4的的hanoi tower问题. 总所周知,\(n\)盘3塔有递推公式\(d[i]=dp[i-1]*2+1\) 令\(f[i ...
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
随机推荐
- Java 中常见数据类型的相互转换
1.将String 转化成 long , 转化成 double String 转化成 long : long i = Long.parseLong(String s); 或 long i = L ...
- JSP的学习二(请求转发与 重定向)
一: 1.介绍知识点 1). 本质区别: 请求的转发只发出了一次请求, 而重定向则发出了两次请求. 具体: ①. 请求的转发: 地址栏是初次发出请求的地址. 请求的重定向: 地址栏不再是初次发出的请 ...
- linux 下rocketmq安装
一.解压mq(/data下)tar -zxvf Rocketmq-3.5.8.tar.gz 二.修改配置文件vi /etc/profileexport rocketmq=/data/alibaba-r ...
- 【知了堂学习笔记】java 编写几种常见排序算法
排序的分类: 一.交换排序 所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动. 1.冒泡 ...
- [js]事件篇
一.事件流 1.冒泡事件:从特定的事件到不特定事件依次触发:(由DOM层次的底层依次向上冒泡) (1)示例: <html onclick="add('html<br>')& ...
- 【mysql】当where后接字符串,查询时会发生什么?
好久没有研究一个“深层次”的问题了. 首先来看我们为什么要讨论这个问题~ 首先这是一个正常的数据库查询,我们可以看到在ruizhi数据库里的chouka表内,所有数据如图. 现在,我们运行查询: se ...
- mongdb 拓展的下载地址和编译安装(php)
下载地址:https://pecl.php.net/package/mongodb 编译安装: $ tar zxvf mongodb-mongodb-php-driver-<commit_id& ...
- “公共语言规范”(CLS)
一.什么是“公共语言规范”(CLS) 定义了一个最小公共集,任何编译器只有支持这个功能集,生成的类型才能兼容其他符合CLS.面向CLR的语言生成的组件 二.CLS规则 类型的每个成员要么是字段(数据) ...
- Mac 上关于TFTP Server 软件的使用
软件下载地址 http://ww2.unime.it/flr/tftpserver/ 软件下载后进行安装,打开软件, 如果出现如下图所示情况 然后当你点击蓝色的Fix 按钮时,如果又出现如下提示 这时 ...
- OpenStack计费项目Cloudkitty系列详解(一)
云计算是一种按需付费的服务模式,虽然OpenStack前期在计量方面走了些“弯路”,但现在的ceilometer.gnocchi.aodh.panko项目的稳步并进算是让其峰回路转.然而,目前来看Op ...



