题目大意:
依次给定多个点(要求第一个点和最后一个点重叠),把前后两个点相连求最后得到的图形的面的个数
根据欧拉定理:
设平面图的顶点数为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 }