人生第一道正儿八经的计算几何题。。。光消编译错误就弄了老半天,果然是够弱。。

题意大概是,给你N条线段,它们会构成一个一笔画的图形,给你先线段的顺序就是一笔画的顺序,线段可能相交但是不会重合

问你最后那个图形可以将平面分成多少个区域(包括有穷区域和无穷区域)

显然这里可以利用欧拉定理来求解,即平面上的点数+面数=边数+2

那么问题就转化为求最后的图形有多少个点和多少条边了。

大体思路是,通过枚举线段来求出所有线段的交点,加上原有题目告诉你的所有线段的起点和终点,可以求得图中所有的点的数量。

但是因为有可能出现三点共线的情况,这样会导致多余的点的出现,因此求出所有的点之后对点集做一次去重处理,可以利用STL里面的unique函数,非常的方便

然后枚举每一个新增的交点,如果这个交点在一个线段之间,那么就会导致一条新边的产生。

由此就完成了边和点的统计

#include <cstdio>
#include <algorithm>
#include <cmath>#define INPUT_FILE "in.txt"
#define OUTPUT_FILE "out.txt"using namespace std;typedef long long LL;
const int maxn = 400;
const double eps = 1e-10;void setfile() {freopen(INPUT_FILE,"r",stdin);freopen(OUTPUT_FILE,"w",stdout);
}struct Point {double x,y;Point(double x = 0,double y = 0):x(x),y(y) {}
};typedef Point Vector;
Point v[maxn * maxn];   //顶点
Point p[maxn];Vector operator - (Point a,Point b) {return Vector(a.x - b.x,a.y - b.y);
}Vector operator * (Vector a,double p) {return Vector(a.x * p,a.y * p);
}Vector operator + (Vector a,Vector b) {return Vector(a.x + b.x,a.y + b.y);
}double dot(Vector a,Vector b) {return a.x * b.x + a.y * b.y;
}int dcmp(double x) {if(fabs(x) < eps) return 0;return x < 0 ? -1 : 1;
}bool operator < (Point a,Point b) {return a.x < b.x || (a.x == b.x && a.y < b.y);
}double cross(Vector a,Vector b) {return a.x * b.y - a.y * b.x;
}bool have_intersection(Point a1,Point a2,Point b1,Point b2) {double c1 = cross(a2 - a1,b1 - a1),c2 = cross(a2 - a1,b2 - a1);double c3 = cross(b2 - b1,a1 - b1),c4 = cross(b2 - b1,a2 - b1);bool ret = (dcmp(c1) * dcmp(c2) < 0) && (dcmp(c3) * dcmp(c4) < 0);return ret;
}bool on_segment(Point p,Point a,Point b) {return dcmp(cross(p - a,p - b)) == 0 && dcmp(dot(a - p,b - p)) < 0;
}Point get_intersection(Point a1,Point a2,Point b1,Point b2) {Vector v = a2 - a1,w = b2 - b1,u = a1 - b1;double t = cross(w,u) / cross(v,w);return a1 + v * t;
}bool operator == (Point a,Point b) {return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}int main() {int n,kase = 1;while(scanf("%d",&n),n) {for(int i = 0;i < n;i++) {scanf("%lf%lf",&v[i].x,&v[i].y);p[i] = v[i];}int cnt_v = n - 1,cnt_f = 0,cnt_e = n - 1;   n--;        //判断一下给定的线段是否有交点for(int i = 0;i < n;i++) {for(int j = i + 1;j < n;j++) {if(have_intersection(p[i],p[i + 1],p[j],p[j + 1])) {//找到交点了就添加到点集里面v[cnt_v++] = get_intersection(p[i],p[i + 1],p[j],p[j + 1]);}}}//特判三点共线的时候的状态sort(v,v + cnt_v);cnt_v = unique(v,v + cnt_v) - v;//处理因为线段交点而新生成的线段for(int i = 0;i < cnt_v;i++) {for(int j = 0;j < n;j++) {if(on_segment(v[i],p[j],p[j + 1])) {cnt_e++;}}}printf("Case %d: There are %d pieces.\n",kase++,2 + cnt_e - cnt_v);}return 0;
}

  

转载于:https://www.cnblogs.com/rolight/p/3691750.html

Poj 2284 That Nice Euler Circuit相关推荐

  1. UVA10735 Euler Circuit题解

    原文链接:http://www.algorithmist.com/index.php/User:Sweepline/UVa_10735.cpp AC的C++语言程序: /* UVa 10735: fi ...

  2. 欧拉路径和欧拉回路(Euler Path and Euler Circuit)解释

    欧拉路径(欧拉回路)是图论非常重要的组成部分,欧拉路径是数学家欧拉在研究著名的德国哥尼斯堡(Koenigsberg)七桥问题时发现的.这一发现直接导致了一门新的理论研究的诞生-图论问题. 欧拉路径和欧 ...

  3. UVA1342 That Nice Euler Circuit(ACM - ICPC 2004 Asia - Shanghai)(计算几何、欧拉定理)

    整理的算法模板合集: ACM模板 欧拉定理:设平面图的顶点数.边数和面数分别为V,E,F,则V+F-E=2. #include<bits/stdc++.h> using namespace ...

  4. LA 3263 That Nice Euler Circuit (2D Geometry)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  5. POJ前面的题目算法思路【转】

    1000 A+B Problem 送分题 49% 2005-5-7 1001 Exponentiation 高精度 85% 2005-5-7 1002 487-3279 n/a 90% 2005-5- ...

  6. POJ 超详细分类

    POJ 各题算法 1000    A+B Problem            送分题     49%    2005-5-7 1001    Exponentiation         高精度   ...

  7. c语言以16进制输出大写字母,【C语言】十六进制形式输出应用程序

    1.前言 最近在看到同事写了一款封印病毒的程序,非常有意思!原理大致是将PE文件中的ASCII转换成HEX输出到文本中.这样做的目的是为了保存病毒样本的时候不会被杀毒软件查杀!然而却是delphi写的 ...

  8. poj 1637(混合图求欧拉回路)

    参考博客:http://www.cnblogs.com/destinydesigner/archive/2009/09/28/1575674.html 1 定义 欧拉通路 (Euler tour)-- ...

  9. matlab求解关键,基于遗传算法的多辆洒水车最优路径求解(其中包含MATLAB的一些关键语句说明和Floyd,Dijkstra,Euler算法).doc...

    基于遗传算法的多辆洒水车最优路径求解(其中包含MATLAB的一些关键语句说明和Floyd,Dijkstra,Euler算法) 摘要 车辆路径问题可以分为以点为服务和以边为服务两种,洒水车问题是以边为服 ...

最新文章

  1. IoT:template
  2. PyQt编程之如何在屏幕中央显示窗体
  3. vs2010开发php,VS2010 下 开发C++
  4. DataGridView控件中显示图片及其注意事项 【z】
  5. python哪个版本支持xp_windows支持哪个版本的python
  6. c语言数据页,c语言基础--数据类型(51页)-原创力文档
  7. 装饰器Decorator(函数的装饰)
  8. Q140:PBRT-V3,各种渲染算法(Integrator,积分器)汇总
  9. phpzend框架_PHP框架Zend
  10. 【经典传颂】人月神话The Mythical Man-Month
  11. 在ROS中创建工作区时出现错误
  12. 正弦余弦定理,求圆弧度或度数
  13. 【算法导论-36】并查集(Disjoint Set)具体解释
  14. linux垃圾文件清理,请问 如何linux 垃圾文件清理、
  15. NXP LPC1768最小系统板Keil开发环境流程演示
  16. PgSQL · 乱入拜年 · 小鸡吉吉和小象Pi吉(PostgreSQL)的鸡年传奇
  17. 程序员与软件工程师的区别
  18. 程序员修炼之道-从小工到专家 读后感
  19. Map.entry详解
  20. Carsim的基本功能介绍

热门文章

  1. 我的年龄又快被5整除了......
  2. 忘掉 Java 并发,先听完这个故事。。。
  3. 反思~我们是否应当克制对新技术的追求?
  4. 几张动态图捋清Java常用数据结构及其设计原理
  5. 从Thread.start()方法看Thread源码,多次start一个线程会怎么样
  6. spring-session使用教程(一):redis共享session
  7. 数据库并发一致性的问题
  8. 【Python】青少年蓝桥杯_每日一题_1.11_奇偶数
  9. instanceof 是什么意思
  10. 计算机启动操作系统的过程,操作系统启动过程