做法:不断的去半平面交
注意点:中垂线的方向,我用的是逆时针边界,当为same时,解在中垂线上,输出0,而且只要有一次输出为0,以后的输出都会为0;
这个题又学到了一个向量旋转的函数。。不错不错~~~~
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const double pi=acos(-1.0);
const double eps=1e-8;
int n,ln,dq[1000000],top,bot,pn,ln2;
double area;
struct P
{
double x,y;
P(){}
P(double x,double y):x(x),y(y){
}
P operator +(P p){
return P(x+p.x,y+p.y);
}
P operator -(P p){
return P(x-p.x,y-p.y);
}
P operator *(double d){
return P(x*d,y*d);
}
P operator /(double d){
return P(x/d,y/d);
}
double det(P p){
return x*p.y-y*p.x;
}
}p[100000];
struct Line
{
P a,b;
double angle;
}l[1000000],l1[1000000];
P in(Line a,Line b)
{
return a.a+(a.b-a.a)*((b.b-b.a).det(b.a-a.a)/(b.b-b.a).det(a.b-a.a));
}
int dblcmp(double k)
{
if(fabs(k)<eps)
return 0;
return k>0?1:-1;
}
bool cmp(Line a,Line b)
{
int d=dblcmp(a.angle-b.angle);
if(!d)
return dblcmp((b.a-a.a).det(b.b-a.a))>0;
return d<0;
}
bool judge(Line a,Line b,Line c)
{
P r=in(b,c);
return dblcmp((a.a-r).det(a.b-r))<0;
}
P A,B;
char s[1000000];
void HPI()
{
int i,j;
for( i=0;i<ln;i++)
l1[i]=l[i];
sort(l1,l1+ln,cmp);
int len;
for(i=0,j=0;i<ln;i++)
{
if(dblcmp(l1[i].angle-l1[j].angle)>0)
l1[++j]=l1[i];
}
len=j+1;
top=1;
bot=0;
dq[0]=0;
dq[1]=1;
for(i=2;i<len;i++)
{
while(top>bot && judge(l1[i],l1[dq[top]],l1[dq[top-1]])) top--;
while(top>bot && judge(l1[i],l1[dq[bot]],l1[dq[bot+1]])) bot++;
dq[++top]=i;
}
while(top>bot && judge(l1[dq[bot]],l1[dq[top]],l1[dq[top-1]])) top--;
while(top>bot && judge(l1[dq[top]],l1[dq[bot]],l1[dq[bot+1]])) bot++;
dq[++top]=dq[bot];
for(i=bot,pn=0;i<top;i++,pn++)
{
p[pn]=in(l1[dq[i]],l1[dq[i+1]]);
}
}
void getarea()
{
if(pn<3)
{
area=0;
}
else
{
for(int i=1;i<pn-1;i++)
{
area+=(p[i]-p[0]).det(p[i+1]-p[0]);
}
area=fabs(area);
area/=2.0;
}
}
//向量的旋转 //底边线段ab 绕a逆时针旋转角度A,b->b1,sinl是sinA的值。
P Whirl(double cosl, double sinl, P a, P b)
{
b.x -= a.x; b.y -= a.y;
P c;
c.x = b.x * cosl - b.y * sinl + a.x;
c.y = b.x * sinl + b.y * cosl + a.y;
return c;
}
int main()
{
A.x=0;
A.y=0;
ln=0;
l[ln].a.x=0;l[ln].a.y=0;l[ln].b.x=10;l[ln].b.y=0;
l[ln].angle=atan2(l[ln].b.y-l[ln].a.y,l[ln].b.x-l[ln].a.x);
ln++;
l[ln].a.x=10;l[ln].a.y=0;l[ln].b.x=10;l[ln].b.y=10;
l[ln].angle=atan2(l[ln].b.y - l[ln].a.y,l[ln].b.x-l[ln].a.x);
ln++;
l[ln].a.x=10;l[ln].a.y=10;l[ln].b.x=0;l[ln].b.y=10;
l[ln].angle=atan2(l[ln].b.y-l[ln].a.y,l[ln].b.x-l[ln].a.x);
ln++;
l[ln].a.x=0;l[ln].a.y=10;l[ln].b.x=0;l[ln].b.y=0;
l[ln].angle=atan2(l[ln].b.y-l[ln].a.y,l[ln].b.x-l[ln].a.x);
ln++;
int flag=0;
while(~scanf("%lf %lf %s",&B.x,&B.y,s))
{
P C=(A+B)/2.0;
area=0;
A=B;
if(s[0]=='H')
{
l[ln].a=C;l[ln].b=Whirl(0,-1,C,B);
l[ln].angle=atan2(l[ln].b.y-l[ln].a.y,l[ln].b.x-l[ln].a.x);
ln++;
}
else if(s[0]=='C')
{
l[ln].a=C;l[ln].b=Whirl(0,1,C,B);
l[ln].angle=atan2(l[ln].b.y-l[ln].a.y,l[ln].b.x-l[ln].a.x);
ln++;
}
else
{
flag=1;
}
if(flag)
printf("0.00\n");
else
{
HPI();
getarea();
printf("%.2lf\n",area);
}
}
return 0;
}