LA3263 一笔画

题目大意:
依次给定多个点(要求第一个点和最后一个点重叠),把前后两个点相连求最后得到的图形的面的个数

根据欧拉定理:

设平面图的顶点数为V,边数为E,面数为F,则V+F-E = 2

这里的E是指如果一条直线上被多个点分割,那么就算多条边

所以我们要求出V和E的值

先求点,已给定的点数,还要包括相连过程中相交得到的点,经过去重得到最后的点数

for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                //if(i==j) continue;
                if(onIntersection(po[i],po[i+1],po[j],po[j+1])){
                    vp.push_back(getLineIntersection(po[i],po[i+1]-po[i],po[j],po[j+1]-po[j]));
                }
            }
        }
        sort(vp.begin(),vp.end());
        c=unique(vp.begin(),vp.end()) - vp.begin(); //去重前要先进行排序,unique是对地址进行操作,所以这里使用数组也可以

然后找边,根据是否有新得到的点出现在边上,若有,每次边数++;

for(int i=0;i<c;i++){
            for(int j=0;j<n;j++){
                if(onSegment(vp[i],po[j],po[j+1]))
                    e++;
            }
        }
     

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <vector>
  4 #include <cmath>
  5 #include <algorithm>
  6 using namespace std;
  7 #define eps 1e-10
  8 struct Point {
  9     double x,y;
 10     Point(double x=0,double y=0):x(x),y(y){}
 11 }po[100005];
 12 typedef Point Vector;
 13 
 14 vector<Point> vp;
 15 
 16 int dcmp(double x)
 17 {
 18     if(abs(x)<eps) return 0;
 19     return x>0?1:-1;
 20 }
 21 
 22 bool operator==(const Point &a,const Point &b){
 23     return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
 24 }
 25 
 26 Vector operator-(Point a,Point b){
 27     return Vector(a.x-b.x,a.y-b.y);
 28 }
 29 
 30 Vector operator+(Vector a,Vector b){
 31     return Vector(a.x+b.x,a.y+b.y);
 32 }
 33 
 34 Vector operator*(Vector a,double b){
 35     return Vector(a.x*b,a.y*b);
 36 }
 37 
 38 Vector operator/(Vector a,double b){
 39     return Vector(a.x/b,a.y/b);
 40 }
 41 
 42 bool operator<(const Point &a,const Point &b){
 43     return a.x<b.x||(a.x==b.x&&a.y<b.y);
 44 }
 45 
 46 double Dot(Vector a,Vector b){
 47     return a.x*b.x + a.y*b.y;
 48 }
 49 
 50 double Cross(Vector a,Vector b){
 51     return a.x*b.y - a.y*b.x;
 52 }
 53 
 54 double Length(Vector a){
 55     return sqrt(Dot(a,a));
 56 }
 57 
 58 double Angle(Vector a,Vector b){
 59     return acos(Dot(a,b) / Length(a) / Length(b));
 60 }
 61 
 62 Point getLineIntersection(Point a,Vector va , Point b , Vector vb){
 63     Vector c = a-b;
 64     double t = Cross(vb,c) / Cross(va,vb);
 65     return a+va*t;
 66 }
 67 
 68 bool onSegment(Point a,Point st,Point la){
 69     return dcmp(Cross(st-a,la-a)) == 0 && dcmp(Dot(st-a,la-a)) < 0;
 70 }
 71 
 72 bool onIntersection(Point a , Point b , Point c , Point d){
 73     double t1 = dcmp(Cross(b-a , c-a)) , t2 = dcmp(Cross(b-a , d-a));
 74     double t3 = dcmp(Cross(d-c , b-c)) , t4 = dcmp(Cross(d-c , a-c));
 75     return t1*t2 < 0 && t3*t4<0;
 76 }
 77 
 78 int main()
 79 {
 80   // freopen("test.in","rb",stdin);
 81     int kase = 0;
 82     int n,x,y,e,c;
 83     while(~scanf("%d",&n)){
 84         if(n==0) break;
 85 
 86         vp.clear();
 87         for(int i=0;i<n;i++){
 88             scanf("%d%d",&x,&y);
 89             po[i].x = x,po[i].y = y;
 90             vp.push_back(po[i]);
 91         }
 92         n--;
 93         e=n;
 94         for(int i=0;i<n;i++){
 95             for(int j=i+1;j<n;j++){
 96                 //if(i==j) continue;
 97                 if(onIntersection(po[i],po[i+1],po[j],po[j+1])){
 98                     vp.push_back(getLineIntersection(po[i],po[i+1]-po[i],po[j],po[j+1]-po[j]));
 99                 }
100             }
101         }
102         sort(vp.begin(),vp.end());
103         c=unique(vp.begin(),vp.end()) - vp.begin();
104         for(int i=0;i<c;i++){
105             for(int j=0;j<n;j++){
106                 if(onSegment(vp[i],po[j],po[j+1]))
107                     e++;
108             }
109         }
110         printf("Case %d: There are %d pieces.
",++kase,e-c+2);
111     }
112     return 0;
113 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/4015070.html