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.\n",++kase,e-c+2);

111     }

112     return 0;

113 }

 

你可能感兴趣的:(a)