程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Poj 2284 Hoj 1890 That Nice Euler Circuit

Poj 2284 Hoj 1890 That Nice Euler Circuit

編輯:C++入門知識

本題用到平面圖的歐拉公式:設平面圖的頂點數、邊數和面數分別為V,E,F,則V+F-E=2. 1.在求頂點數V的時候,很容易想到的想法是判斷線段兩兩相交,如果兩線段相交,則頂點數+1,但是,兩頂點可能會重合,所以必須要求出相交點的坐標。然後去掉重復的頂點,即去掉坐標值相同的頂點,那麼此時數組的大小就是V。先用sort排序,再用unique去重。 2.在求E的時候,需要對每個V中的頂點做判斷,如果點c在線段(a,b)上,不包含端點,那麼線段數目+1,求完以後,加上原來的初始化的線段數即可。 3.依據歐拉公式求F。 [cpp]   #include <iostream>   #include <stdio.h>   #include <stdlib.h>   #include <string.h>   #include <math.h>   #include <algorithm>   using namespace std;      const double eps = 1e-8;      struct Point   {       double x;       double y;       Point() {}       Point(double _x,double _y):x(_x),y(_y) {}       friend Point operator + (Point a,Point b)       {           return Point(a.x+b.x , a.y+b.y);       }       friend Point operator - (Point a,Point b)       {           return Point(a.x-b.x , a.y-b.y);       }   };      struct Edge   {       Point a;       Point b;   };   Edge e[315];   Point p_temp[315];   Point p[100000];   int p_num = 0;      int dcmp(double x)  //三態函數   {       if(fabs(x)<eps)//在一定的精度范圍內可認為是0           return 0;       return x>0?1:-1;   }   double det(Point a,Point b)  // 叉積,重載叉積函數   {       return a.x*b.y-a.y*b.x;   }   double det(Point a,Point b,Point o)  // 叉積   {       return det(a-o,b-o);   }   double det(Point a,Point b,Point c,Point d)  // 叉積   {       return det(b-a,d-c);   }      double dot(Point a,Point b)  // 點積   {       return a.x*b.x + a.y*b.y;   }   double dot(Point a,Point b,Point o)  // 點積   {       return dot(a-o,b-o);   }   void intersect(Point a,Point b,Point c,Point d)// 判斷線段是否相交   {       int d1 = dcmp( det(a,b,c) );       int d2 = dcmp( det(a,b,d) );       int d3 = dcmp( det(c,d,a) );       int d4 = dcmp( det(c,d,b) );       Point temp;       //求交點坐標       if((d1*d2<0&&d3*d4<0))       {           double t = ((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));           temp.x = a.x + (b.x - a.x) * t;           temp.y = a.y + (b.y - a.y) * t;           p[p_num++] = temp;       }       //c在(a,b)上       else if(d1==0&&dcmp(dot(a,b,c))<=0)       {           temp.x = c.x;           temp.y = c.y;           p[p_num++] = temp;       }       //d在(a,b)上       else if(d2==0&&dcmp(dot(a,b,d))<=0)       {           temp.x = d.x;           temp.y = d.y;           p[p_num++] = temp;       }       //a在(c,d)上       else if(d3==0&&dcmp(dot(c,d,a))<=0)       {           temp.x = a.x;           temp.y = a.y;           p[p_num++] = temp;       }       //b在(c,d)上       else if(d4==0&&dcmp(dot(c,d,b))<=0)       {           temp.x = b.x;           temp.y = b.y;           p[p_num++] = temp;       }   }   //從大到小排序   bool cmp(Point a,Point b)   {       if(a.x - b.x >eps)       {           return true;       }       else if(fabs(a.x - b.x)<eps && a.y - b.y >eps)       {           return true;       }       return false;      }   //兩點坐標相等   bool cmp2(Point a,Point b)   {       if(fabs(a.x - b.x) < eps && fabs(a.y - b.y)<eps)       {           return true;       }       return false;   }   int main()   {   #ifndef ONLINE_JUDGE       freopen("in.txt","r",stdin);   #endif       int n;       int num = 0;       while(scanf(" %d",&n)!=EOF && n!=0)       {           num++;           p_num = 0;           for(int i=1;i<=n;i++)           {               scanf(" %lf %lf",&p_temp[i].x,&p_temp[i].y);           }           for(int i=1;i<n;i++)           {               e[i].a.x = p_temp[i].x;               e[i].a.y = p_temp[i].y;               e[i].b.x = p_temp[i+1].x;               e[i].b.y = p_temp[i+1].y;           }           n--;           int E = n;           int V = 0;           for(int i=1;i<n;i++)           {               for(int j=i+1;j<=n;j++)               {                   intersect(e[i].a,e[i].b,e[j].a,e[j].b);               }           }              sort(p,p + p_num,cmp);           p_num = unique(p,p+p_num,cmp2) - p;           V = p_num;           for(int i=0;i<V;i++)           {               for(int j=1;j<=n;j++)               {                   //判斷頂點是否在線段上                   if( dcmp(det(e[j].a,e[j].b,p[i])) == 0 && dcmp(dot(e[j].a,e[j].b,p[i]))<0 )                   {                       E++;                   }               }           }           printf("Case %d: There are %d pieces.\n",num,2+E-V);       }       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved