平面图中的欧拉定理
来源:互联网 发布:伞齿轮参数计算软件 编辑:程序博客网 时间:2024/05/01 07:32
定理:设G为任意的连通的平面图,则v-e+f=2,v是G的顶点数,e是G的边数,f是G的面数。
题目描述:给出一个一笔画图形的n个节点的坐标,请你求解这个图形把平面分成了几个面
一笔画图形一个是把图上所有的边仅且遍历一次的封闭连通图。
分析:求面的问题就分解为求顶点个数与边条数的问题。
点的求法:遍历每条线段,如果是规范相交,则将该点存入V[]数组中。最后对V[]数组进行排序,使用STL中的unique()函数对求出来的交点进行去重处理。
边的求法:遍历每个交点和每条线段,如果交点在线段上,边数加一
//欧拉定理#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string.h>#include <vector>using namespace std;struct point{ double x, y; point(double x = 0.0, double y = 0.0) :x(x), y(y) {};};typedef point Vector;const double eps = 1e-8;//判断double类型(x)与0的大小int dcmp(double x) { if (fabs(x)<eps) return 0; return (x<0) ? -1 : 1; }//向量的运算符重载Vector operator + (Vector A, Vector B) { return Vector(A.x + B.y, A.y + B.y); }Vector operator - (Vector A, Vector B) { return Vector(A.x - B.y, A.y - B.y); }Vector operator * (Vector A, double p) { return Vector(p * A.x, p * A.y); }Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y / p); }bool operator < (const point& a, const point& b) {//判断a点是否小于b点 return a.x < b.x || (a.x == b.x && a.y < b.y);}bool operator == (const point& a, const point &b) {//判断两个点是否相等 return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;}//向量的运算double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }//向量的点乘double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }//向量的叉积 //判断规范相交bool SegmentProperIntersection(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); return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;}//两直线交点(参数法)point GetLineIntersection(point P, Vector v, point Q, Vector w) { Vector u = P - Q; double t = Cross(w, u) / Cross(v, w); return P + v*t;}//判断点p是否在线段a1a2上(叉乘=0;点乘<0)bool OnSegment(point p, point a1, point a2){ return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p))<0;}const int maxn = 300 + 10;point P[maxn], V[maxn * maxn];int main(){ int n, kase = 0, c, e; while (~scanf("%d", &n) && n) { for (int i = 0; i < n; i++) { scanf("%d%d", &P[i].x, &P[i].y); V[i] = P[i]; } c = n - 1; e = n - 1; for (int i = 0; i < c; i++)//遍历每个点 for (int j = i + 1; j < c; j++) if (SegmentProperIntersection(P[i], P[i + 1], P[j], P[j + 1]))//如果是规范相交 V[c++] = GetLineIntersection(P[i], P[i + 1] - P[i], P[j], P[j + 1] - P[j]);//把交点存入V[]中 sort(V, V + c); c = unique(V, V + c) - V;//把重复元素放到数组后面,c为(去重后)交点的个数 for (int i = 0; i < c; i++)//遍历每个交点 for (int j = 0; j < n - 1; j++)//遍历每条线段 if (OnSegment(V[i], P[j], P[j + 1])) e++;//如果交点在线段上,边数加一 printf("Case %d: There are %d pieces.\n", ++kase, e + 2 - c); }}
0 0
- 平面图中的欧拉定理
- [平面图欧拉定理]ONTAK2015. Ogród zoologiczny
- LA3263 平面图的欧拉公式
- 平面图欧拉公式的精彩证明
- 费马小定理&&欧拉定理
- 威尔逊定理,费马小定理,欧拉定理
- 欧拉定理
- 欧拉定理证明
- 欧拉定理
- 【数论】欧拉定理
- 欧拉定理
- 欧拉定理
- 欧拉定理
- 欧拉定理
- 欧拉定理
- 扩展欧拉定理
- 浅谈欧拉定理
- 扩展欧拉定理
- this指针
- 加载网页时弹出div
- 简易redis的使用
- 3G手机开发之Android应用开发教程+源码
- FragmentTabHost中添加多层fragment 的注意事项
- 平面图中的欧拉定理
- qt5 qwt 插件目录
- Microsoft Visual Studio 2010创建C语言程序的步骤
- Flask Web 开发 数据库迁移
- VBA编程一例:解决WORD文档无法显示链接的图像问题
- File
- Android横屏开发的老梗---Fragment切换混乱重叠问题
- POJ 2513 Colored Sticks
- JAVA设计模式-模板方法模式