题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21363

【思路】

欧拉定理:V+F-E=2。则F=E-V+2。

其中V E F分别代表平面图的顶点数,边数和面数。

涉及到判断线段是否有交点,直线求交点以及判断点是否在直线上的函数。注意求直线交点之前需要判断是否有交点,交点还需要去重。

【代码】

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define FOR(a,b,c) for(int a=(b);a<(c);a++)
  6. using namespace std;
  7.  
  8. const double eps = 1e-;
  9. int dcmp(double x) {
  10. if(fabs(x)<eps) return ; else return x<? -:;
  11. }
  12.  
  13. struct Pt {
  14. double x,y;
  15. Pt(double x=,double y=):x(x),y(y) {};
  16. };
  17. typedef Pt vec;
  18.  
  19. vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
  20. vec operator + (vec A,vec B) { return vec(A.x+B.x,A.y+B.y); }
  21. vec operator * (vec A,double p) { return vec(A.x*p,A.y*p); }
  22. double Dot(vec A,vec B) { return A.x*B.x+A.y*B.y; }
  23. double cross(vec A,vec B) { return A.x*B.y-A.y*B.x; }
  24. bool operator < (const Pt& a,const Pt& b) {
  25. return a.x<b.x || (a.x==b.x && a.y<b.y);
  26. }
  27. bool operator == (const Pt& a,const Pt& b) { // for unique
  28. return dcmp(a.x-b.x)== && dcmp(a.y-b.y)==;
  29. }
  30.  
  31. Pt LineIntersection(Pt P,vec v,Pt Q,vec w) {
  32. vec u=P-Q;
  33. double t=cross(w,u)/cross(v,w);
  34. return P+v*t;
  35. }
  36. bool SegIntersection(Pt a1,Pt a2,Pt b1,Pt b2) {
  37. double c1=cross(a2-a1,b1-a1) , c2=cross(a2-a1,b2-a1) ,
  38. c3=cross(b2-b1,a1-b1) , c4=cross(b2-b1,a2-b1);
  39. return dcmp(c1)*dcmp(c2)< && dcmp(c3)*dcmp(c4)<;
  40. // b1 b2在线段a1a2的两侧 a1 a2在线段b1b2的两侧 => 规范相交
  41. }
  42. bool OnSeg(Pt P,Pt a1,Pt a2) {
  43. return dcmp(cross(a1-P,a2-P))== && dcmp(Dot(a1-P,a2-P))<;
  44. }
  45.  
  46. const int N = +;
  47. Pt P[N],V[N*N];
  48. int n;
  49.  
  50. int main() {
  51. int kase=;
  52. while(scanf("%d",&n)== && n) {
  53. FOR(i,,n)
  54. scanf("%lf%lf",&P[i].x,&P[i].y) , V[i]=P[i];
  55. n--;
  56. int c=n,e=n;
  57. FOR(i,,n) FOR(j,i+,n)
  58. if(SegIntersection(P[i],P[i+],P[j],P[j+]))
  59. V[c++]=LineIntersection(P[i],P[i+]-P[i],P[j],P[j+]-P[j]);
  60. sort(V,V+c);
  61. c=unique(V,V+c)-V;
  62. FOR(i,,c) FOR(j,,n)
  63. if(OnSeg(V[i],P[j],P[j+])) e++;
  64. printf("Case %d: There are %d pieces.\n",++kase,e+-c);
  65. }
  66. return ;
  67. }

UVAlive 3263 That Nice Euler Circuit(欧拉定理)的更多相关文章

  1. UVALive - 3263 That Nice Euler Circuit (几何)

    UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址:  UVALive - 3263 That Nice Euler Circuit 题意:  给 ...

  2. LA 3263 That Nice Euler Circuit(欧拉定理)

    That Nice Euler Circuit Little Joey invented a scrabble machine that he called Euler, after the grea ...

  3. uvalive 3263 That Nice Euler Circuit

    题意:平面上有一个包含n个端点的一笔画,第n个端点总是和第一个端点重合,因此团史一条闭合曲线.组成一笔画的线段可以相交,但是不会部分重叠.求这些线段将平面分成多少部分(包括封闭区域和无限大区域). 分 ...

  4. UVALive 3263: That Nice Euler Circuit (计算几何)

    题目链接 lrj训练指南 P260 //==================================================================== // 此题只需要考虑线 ...

  5. UVALi 3263 That Nice Euler Circuit(几何)

    That Nice Euler Circuit [题目链接]That Nice Euler Circuit [题目类型]几何 &题解: 蓝书P260 要用欧拉定理:V+F=E+2 V是顶点数; ...

  6. 简单几何(求划分区域) LA 3263 That Nice Euler Circuit

    题目传送门 题意:一笔画,问该图形将平面分成多少个区域 分析:训练指南P260,欧拉定理:平面图定点数V,边数E,面数F,则V + F - E =  2.那么找出新增的点和边就可以了.用到了判断线段相 ...

  7. hdu 1665 That Nice Euler Circuit(欧拉定理)

    输入n个点,然后从第一个点开始,依次链接点i->点i+1,最后回到第一点(输入中的点n),求得到的图形将平面分成了多少部分. 根据欧拉定理 v_num + f_num - e_num = 2可知 ...

  8. poj2284 That Nice Euler Circuit(欧拉公式)

    题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k( ...

  9. POJ2284 That Nice Euler Circuit (欧拉公式)(计算几何 线段相交问题)

                                                          That Nice Euler Circuit Time Limit: 3000MS   M ...

随机推荐

  1. XmlHttpRequest 使用

    1. IE7以后对xmlHttpRequest 对象的创建在不同浏览器上是兼容的.下面的方法是考虑兼容性的,实际项目中一般使用Jquery的ajax请求,可以不考虑兼容性问题. function ge ...

  2. Java文件File操作一:文件的创建和删除

    一.简述 File 文件类,主要对文件进行相关操作.常用的File操作有:文件(夹)的创建.文件(夹)的删除,文件的读入和下载(复制)等: 二.文件(夹)的创建和删除 1.创建过程 实例: //cre ...

  3. oracle的学习 第二节:创建数据表

    学习内容: A.创建数据库和表空间 B.创建用户和分配权限 C.创建数据表 一.创建数据库和表空间 (一)SQL语言的基本概念 1.概念 高级的结构化查询语言:沟通数据库服务器和客户的重要桥梁. PL ...

  4. Linux/Unix下设置定时任务

    Unix系统提供了cron和at命令,使系统和用户可以定时运行一定的程序,而不需手工启动. 使用cron用于周期性的执行一个命令,为了使用它,必须编辑crontab文件.系统缺省的/etc/cront ...

  5. Object-C添加方法

    给实例变量添加getter方法: #import <Cocoa/Cocoa.h> @interface Photo:NSObject { NSString *caption; NSStri ...

  6. C++自定义异常处理

    自定义异常类 class MyException { public: MyException() { } MyException(char* str) { msg = str; } MyExcepti ...

  7. Linux下彻底卸载LibreOffice方法

    Linux下彻底卸载LibreOffice方法 终端中输入命令: 对所有基于 Debian 的发行版(Debian.Ubuntu.Kubuntu.Xubuntu.*buntu.Sidux 等): su ...

  8. Gherkin学习笔记

    前言 由于项目准备使用BDD模式开发,所以最近在学习BDD,同时也记录下自己的学习点滴. 参考原文:https://github.com/cucumber/cucumber/wiki/Gherkin ...

  9. pgsql与mysql 下 varchar类型的数字文本的排序 区别

    两者都有cast函数,但使用方法完全不同. 1.在mysql中,cast( value as type) 将value的数据类型转换成type类型,其type可以为 二进制,同带binary前缀的效果 ...

  10. Yeoman安装

    Yeoman帮助我们创建项目,提供更好的工具来使我们的项目更多样化. Yeoman提供generator系统,一个generator是一个插件,在我们在一个完整的项目上使用‘yo’命令时,会运行该ge ...