直接就是欧拉定理:设平面图的顶点数为,边数,和面数分别为V,E和F,则V+ F-E=2;
所以就只需要算顶点数和边数就好了。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<iostream>
#include<complex>
#include<string>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define nn 330
#define LL long long
#define ULL unsiged long long
#define mod 0x7fffffff
#define inf oxfffffffffff
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
((`'-"` `""-'`))
) - - (
/ (o _ o) \
\ ( 0 ) /
_'-.._ '=' _..-'_
/`;#'#'#. -. #'#'#;`\
\_)) '#' ((_/
#. ☆ ☆ ☆ .#
'#. 求 A C! .#'
/'#. .#'\
_\\'#. .#'//_
(((___)'#'(___)))
struct node
{
double x,y;
node(double x=0,double y=0):x(x),y(y){}
};
typedef node point;
point operator + (node A,node B)//加
{
return point(A.x+B.x,A.y+B.y);
}
point operator - (node A,node B)//减
{
return point(A.x-B.x,A.y-B.y);
}
point operator * (node A,double p)//数乘
{
return point(A.x*p,A.y*p);
}
point operator / (node A,double p)//除
{
return point(A.x/p,A.y/p);
}
bool operator < (const point& A,const point& B)//比较大小
{
return A.x<B.x||(A.x==B.x&&A.y<B.y);
}
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}
bool operator == (const point& a,const point& b)//比较是不是同一点
{
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}
double dot(node A,node B)//点积
{
return A.x*B.x+A.y*B.y;
}
double length(node A)//长度
{
return sqrt(dot(A,A));
}
double angle(node A,node B)//夹角
{
return acos(dot(A,B) / length(A)/length(B));
}
double cross(node A,node B)//叉积
{
return A.x*B.y-A.y*B.x;
}
point Rotate(point A,double rad)//旋转rad角度
{
return point(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
point normal(point A)//旋转90的情况
{
double L=length(A);
return point(-A.y/L,A.x/L);
}
point gli(point P,point V,point Q,point W)//求直线P+Vt和直线Q+Wt的交点
{
point u=P-Q;
double t=cross(W,u)/cross(V,W);
return P+V*t;
}
point distl(point p,point a,point b)//点p到a,b所表示直线的距离
{
point v1=b-a,v2=p-a;
return fabs(cross(v1,v2)/length(v1));
}
point dists(point p,point a,point b)//点p到线段ab的距离
{
if(a==b) return length(p-a);
point v1=b-a,v2=p-a,v3=p-b;
if(dcmp(dot(v1,v2))<0) return length(v2);
else if(dcmp(dot(v1,v2))>0) return length(v3);
else return fabs(cross(v1,v2)/length(v1));
}
point getlp(point P,point A,point B)//点到直线的投影
{
point v=B-A;
return A+v*(dot(v,P-A)/dot(v,v));
}
bool segpi(point a1,point a2,point b1,point b2)//判断线段相交
{
double c1=cross(a2-a1,b1-a1);
double c2=cross(a2-a1,b2-a1);
double c3=cross(b2-b1,a1-b1);
double c4=cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
bool ons(point p,point a1,point a2)//判断点是否在线段上
{
return dcmp(cross(a1-p,a2-p))==0 && dcmp(dot(a1-p,a2-p))<0;
}
point p[nn],v[nn*nn];
int main()
{
int n,kcae=1;
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
v[i]=p[i];
}
n--;
int c=n,e=n;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(segpi(p[i],p[i+1],p[j],p[j+1]))
v[c++]=gli(p[i],p[i+1]-p[i],p[j],p[j+1]-p[j]);
}
}
sort(v,v+c);
c=unique(v,v+c)-v;
for(int i=0;i<c;i++)
{
for(int j=0;j<n;j++)
{
if(ons(v[i],p[j],p[j+1]))
e++;
}
}
printf("Case %d: There are %d pieces.\n",kcae++,e+2-c);
}
return 0;
}
// ...|||||||||||||||∞ |||||
// ╭||||━━ ━━ ||||╮
// ╰||| ~ |||╯
// ||╰╭--╮ˋ╭--╮╯||
// || ╰/ / \ \╯|| ОО