3263 - That Nice Euler Circuit
这是紫书上的模板题,唯一有点思维的地方是用到欧拉公式,关于欧拉公式的简单证明可以看这篇blog
#include
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define ms(x,v) memset((x),(v),sizeof(x))
#define eps 1e-10
#define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1))
using namespace std;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;
const int maxn = 300+10;
struct Point{
double x,y;
Point(double _x=0,double _y=0):x(_x),y(_y){}
void print(){
std::cout << x <<" " <'\n';
}
bool operator < (const Point & p)
{
return x < p.x || (x == p.x && y < p.y);
}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A,double a){return Vector(a*A.x,a*A.y);}
Vector operator / (Vector A,double p){return A*(1/p);}
bool operator == (const Point A,const Point B){return !dcmp(A.x-B.x) && !dcmp(A.y-B.y);}
double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;}
double Length(Vector & A){return sqrt(Dot(A,A));}
double Angle(Vector &A,Vector & B){return acos(Dot(A,B)/Length(A)/Length(B));}
Vector Rotate(Vector &A,double rad){return Vector(A.x*cos(rad)-sin(rad)*A.y,A.x*sin(rad)+A.y*cos(rad));}
Vector Normal(Vector A){//A 的单位法向量
double L = Length(A);
return Vector(-A.y/L,A.x/L);
}
double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}
double Area2(Point A,Point B,Point C){return Cross(B-A,C-A);}
Point GetLineIntersection(Point P,Vector v, Point Q,Vector w){
//计算交点,当v,w平行时无效
Point u = P-Q;
double t = Cross(v,u) / Cross(v,w);
return Q+w*t;
}
double Dis2Line(Point &P,Point & A,Point & B){
//点p到A,B的距离
Vector u1 = P-A;
Vector u2 = B-A;
return abs(Cross(u1,u2)/Length(u2));
}
Point GetLineProjection(Point &P,Point &A,Point & B){
//the projection Point Q of P to Line A,B;
Vector v = B-A;
return A+ v*(Dot(v,P-A)/Dot(v,v));
}
bool SegInsertion(Point A1,Point A2,Point B1,Point B2){
double c1 = Cross(A2-A1,B1-A1),c2 = Cross(A2-A1,B2-A1);
double c3 = Cross(B2-B1,A1-B1),c4 = Cross(B2-B1,A2-B1);
return dcmp(c1)*dcmp(c2) <0 && dcmp(c3)*dcmp(c4) <0;
}
bool onSegment(Point P,Point A,Point B){
return dcmp(Cross(A-P,B-P))==0 && dcmp(Dot(A-P,B-P)) <0;
}
//多边形
double polygonArea(Point *p,int n){
double area =0;
for(int i=1 ; i1 ; ++i)
area += Cross(p[i]-p[0],p[i+1]-p[0]);
return area/2;
}
const int N = 305;
Point p[N],V[N*N];
int main()
{
int n;
int kase = 0;
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(SegInsertion(p[i],p[i+1],p[j],p[j+1]))
V[c++] = GetLineIntersection(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(onSegment(V[i],p[j],p[j+1]))
e++;
printf("Case %d: There are %d pieces.\n",++kase,e+2-c);
}
return 0;
}