| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
AC了,果断贴代码Source Code
Problem: 2839 User: JiaJunpeng
Memory: 4228K Time: 5860MS
Language: C++ Result: Accepted
Source Code
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
int id,n,m,top,num[3];
double S,S1,S2,S3,xx,yy,eps=1e-7,pi=acos(-1.00),x,y,oox=100000000.00,ooy=123456789.000;
struct point
{
double x,y;
int id1,id2;
bool operator <(const point &temp)const
{
if(abs((y-yy)*(temp.x-xx)-(x-xx)*(temp.y-yy))<eps)
return abs(x-xx)+abs(y-yy)<abs(temp.x-xx)+abs(temp.y-yy);
return (y-yy)*(temp.x-xx)-(x-xx)*(temp.y-yy)<0;
}
};
point poly[100001],stack[100001],tri[3],list[10][2];
bool out[10];
struct segment
{
int l,r;
double area;
};
segment tree[1000000];
int inter(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
{
double ru1,ru2,A,B;
A=(y2-y1)*(x4-x3)-(x2-x1)*(y4-y3);
B=(y3-y1)*(x4-x3)-(x3-x1)*(y4-y3);
if(fabs(A)<eps)
return 0;
ru1=B/A;
B=(y3-y1)*(x2-x1)-(x3-x1)*(y2-y1);
ru2=B/A;
x=x1+ru1*(x2-x1);
y=y1+ru1*(y2-y1);
if(((x<x1+eps&&x>x2-eps)||(x<x2+eps&&x>x1-eps))&&((y<y1+eps&&y>y2-eps)||(y<y2+eps&&y>y1-eps)))
{
if(((x<x3+eps&&x>x4-eps)||(x<x4+eps&&x>x3-eps))&&((y<y3+eps&&y>y4-eps)||(y<y4+eps&&y>y3-eps)))
return 2;
return 1;
}
return 0;
}
double cross(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
}
double comarea(double x1,double y1,double x2,double y2,double x3,double y3)
{
return fabs((y2-y1)*x3-(x2-x1)*y3+x2*y1-x1*y2)/2.0;
}
double dist(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double comarg(double x,double y)
{
double res,l=sqrt(x*x+y*y);
res=asin(y/l);
if(x==0)
{
if(y>0)
return pi/2;
else
return 3*pi/2;
}
if(y==0)
{
if(x>0)
return 0.00;
else
return pi;
}
if(x<=0&&y>=0)
res=pi-res;
else if(x<=0&&y<=0)
res=pi-res;
else if(x>=0&&y<=0)
res+=2*pi;
return res;
}
void build(int left,int right,int id)
{
int mid=(left+right)>>1,l=2*id+1,r=2*id+2,id1,id2,id3,id4;
double value;
tree[id].l=left;
tree[id].r=right;
if(left==right)
{
tree[id].area=0.00;
return;
}
build(left,mid,l);
build(mid+1,right,r);
id1=left%n;
id2=mid%n;
id3=(mid+1)%n;
id4=right%n;
value=comarea(stack[id1].x,stack[id1].y,stack[id2].x,stack[id2].y,stack[id3].x,stack[id3].y)+comarea(stack[id1].x,stack[id1].y,stack[id3].x,stack[id3].y,stack[id4].x,stack[id4].y);
tree[id].area=tree[l].area+tree[r].area+value;
}
double query(int left,int right,int id)
{
int id1,id2,id3,id4,l=2*id+1,r=2*id+2;
double res;
if(tree[id].l==left&&tree[id].r==right)
return tree[id].area;
if(tree[l].r<left)
return query(left,right,r);
else if(tree[r].l>right)
return query(left,right,l);
else
{
double v1=query(left,tree[l].r,l),v2=query(tree[r].l,right,r);
res=v1+v2;
id1=left%n;
id2=tree[l].r%n;
id3=tree[r].l%n;
id4=right%n;
res+=comarea(stack[id1].x,stack[id1].y,stack[id2].x,stack[id2].y,stack[id3].x,stack[id3].y);
res+=comarea(stack[id3].x,stack[id3].y,stack[id4].x,stack[id4].y,stack[id1].x,stack[id1].y);
return res;
}
}
int findinter(int id,double x1,double y1,double x2,double y2)
{
int idd,i,s,p,q,id1,id2,id3,id4,left,right,mid,ip1,ip2,ip,res=0,value;
double l,in,arg,arg1,arg2,dx,dy;
left=0;
right=n-1;
l=dist(x1,y1,x2,y2);
dx=x2-x1;
dy=y2-y1;
arg=comarg(dx,dy);
while(left<right-1)
{
mid=(left+right)>>1;
id1=mid%n;
id2=(mid+1)%n;
if(comarg(stack[id2].x-stack[id1].x,stack[id2].y-stack[id1].y)<=arg)
left=mid;
else
right=mid-1;
}
id1=right%n;
id2=(right+1)%n;
if(comarg(stack[id2].x-stack[id1].x,stack[id2].y-stack[id1].y)<=arg)
left=right;
else
{
id1=left%n;
id2=(left+1)%n;
if(comarg(stack[id2].x-stack[id1].x,stack[id2].y-stack[id1].y)>arg)
left=(left+n-1)%n;
}
ip1=(left+1)%n;
dx=-dx;
dy=-dy;
arg=comarg(dx,dy);
left=0;
right=n-1;
while(left<right-1)
{
mid=(left+right)>>1;
id1=mid%n;
id2=(mid+1)%n;
if(comarg(stack[id2].x-stack[id1].x,stack[id2].y-stack[id1].y)<=arg)
left=mid;
else
right=mid-1;
}
id1=right%n;
id2=(right+1)%n;
if(comarg(stack[id2].x-stack[id1].x,stack[id2].y-stack[id1].y)<=arg)
left=right;
else
{
id1=left%n;
id2=(left+1)%n;
if(comarg(stack[id2].x-stack[id1].x,stack[id2].y-stack[id1].y)>arg)
left=(left+n-1)%n;
}
ip2=(left+1)%n;
if(inter(stack[ip1].x,stack[ip1].y,stack[ip2].x,stack[ip2].y,x1,y1,x2,y2)>0)
{
if(fabs(cross(stack[ip1].x-x1,stack[ip1].y-y1,x2-x1,y2-y1))<eps||fabs(cross(stack[ip2].x-x1,stack[ip2].y-y1,x2-x1,y2-y1))<eps)
{
if(id<3)
{
out[id]=true;
out[(id+1)%3]=true;
}
return 0;
}
left=ip1;
right=ip2;
while(left>right)
right+=n;
ip=right%n;
while(left<right-1)
{
mid=(left+right)>>1;
idd=mid%n;
if(cross(stack[idd].x-x,stack[idd].y-y,x2-x1,y2-y1)*cross(stack[ip].x-x,stack[ip].y-y,x2-x1,y2-y1)<eps)
left=mid;
else
right=mid-1;
}
idd=right%n;
if(cross(stack[idd].x-x,stack[idd].y-y,x2-x1,y2-y1)*cross(stack[ip].x-x,stack[ip].y-y,x2-x1,y2-y1)<eps)
left=right;
id1=left%n;
id2=(left+1)%n;
value=inter(stack[id1].x,stack[id1].y,stack[id2].x,stack[id2].y,x1,y1,x2,y2);
if(value==2)
res++;
list[id][1].x=x;
list[id][1].y=y;
list[id][1].id1=id1;
list[id][1].id2=id2;
left=ip2;
right=ip1;
while(left>right)
right+=n;
ip=right%n;
while(left<right-1)
{
mid=(left+right)>>1;
idd=mid%n;
if(cross(stack[idd].x-x,stack[idd].y-y,x1-x2,y1-y2)*cross(stack[ip].x-x,stack[ip].y-y,x1-x2,y1-y2)<eps)
left=mid;
else
right=mid-1;
}
idd=right%n;
if(cross(stack[idd].x-x,stack[idd].y-y,x1-x2,y1-y2)*cross(stack[ip].x-x,stack[ip].y-y,x1-x2,y1-y2)<eps)
left=right;
id1=left%n;
id2=(left+1)%n;
value=inter(stack[id1].x,stack[id1].y,stack[id2].x,stack[id2].y,x1,y1,x2,y2);
if(value==2)
res++;
list[id][0].x=x;
list[id][0].y=y;
list[id][0].id1=id1;
list[id][0].id2=id2;
}
return res;
}
double com(int id1,int id2)
{
double res;
id1%=n;
id2%=n;
if(id1>id2)
res=query(id1,n,0)+query(0,id2,0)+comarea(stack[id1].x,stack[id1].y,stack[id2].x,stack[id2].y,stack[0].x,stack[0].y);
else
res=query(id1,id2,0);
return res;
}
int main()
{
int i,j,s,p,q,id1,id2,id3,id4,left,right,mid,ip1,ip2,value;
double l,in,arg,arg1,arg2,dx,dy;
scanf("%d",&n);
in=1000000000;
for(i=0;i<n;i++)
{
scanf("%lf%lf",&poly[i].x,&poly[i].y);
if(in>poly[i].y)
{
in=poly[i].y;
id=i;
}
}
swap(poly[id],poly[0]);
xx=poly[0].x;
yy=poly[0].y;
sort(poly+1,poly+n);
stack[0]=poly[0];
stack[1]=poly[1];
top=2;
for(i=2;i<n;i++)
{
while(top>=2&&(stack[top-1].y-stack[top-2].y)*(poly[i].x-stack[top-2].x)>(stack[top-1].x-stack[top-2].x)*(poly[i].y-stack[top-2].y)-eps)
top--;
stack[top++]=poly[i];
}
n=top;
build(0,n,0);
scanf("%d",&m);
for(i=0;i<m;i++)
{
double ans;
for(j=0;j<3;j++)
scanf("%lf%lf",&tri[j].x,&tri[j].y);
while(tri[0].x==tri[1].x&&tri[0].y==tri[1].y);
while(tri[0].x==tri[2].x&&tri[0].y==tri[2].y);
while(tri[1].x==tri[2].x&&tri[1].y==tri[2].y);
xx=tri[0].x;
yy=tri[0].y;
sort(tri+1,tri+3);
memset(out,false,sizeof(out));
for(j=0;j<3;j++)
{
num[j]=findinter(j,tri[j].x,tri[j].y,tri[(j+1)%3].x,tri[(j+1)%3].y);
value=findinter(4,tri[j].x,tri[j].y,oox,ooy);
if(value%2==0)
out[j]=true;
}
for(j=0;j<3;j++)
{
if(out[j]==false||num[j]>0)
break;
}
S=comarea(tri[0].x,tri[0].y,tri[1].x,tri[1].y,tri[2].x,tri[2].y);
x=(stack[0].x+stack[1].x)/2.00;
y=(stack[0].y+stack[1].y)/2.00;
S1=comarea(tri[0].x,tri[0].y,tri[1].x,tri[1].y,x,y);
S2=comarea(tri[1].x,tri[1].y,tri[2].x,tri[2].y,x,y);
S3=comarea(tri[2].x,tri[2].y,tri[0].x,tri[0].y,x,y);
if(j>=3&&fabs(S-S1-S2-S3)>eps)
puts("0");
else
{
ans=tree[0].area;
for(j=0;j<3;j++)
{
id1=list[j][0].id2;
id2=list[j][1].id1;
if(((!out[j]||!out[(j+1)%3])||num[j]>1)&&list[j][0].id1!=list[j][1].id1)
{
ans-=com(id1,id2);
ans-=comarea(list[j][0].x,list[j][0].y,stack[id1].x,stack[id1].y,list[j][1].x,list[j][1].y);
ans-=comarea(stack[id1].x,stack[id1].y,stack[id2].x,stack[id2].y,list[j][1].x,list[j][1].y);
}
if(!out[j])
{
id1=j;
id2=(j+2)%3;
if(list[id1][0].id1!=list[id2][1].id1)
{
ip1=list[id1][0].id2;
ip2=list[id2][1].id1;
ans+=com(ip1,ip2);
ans+=comarea(list[id1][0].x,list[id1][0].y,stack[ip1].x,stack[ip1].y,stack[ip2].x,stack[ip2].y);
ans+=comarea(stack[ip2].x,stack[ip2].y,list[id2][1].x,list[id2][1].y,list[id1][0].x,list[id1][0].y);
}
ans+=comarea(tri[j].x,tri[j].y,list[id1][0].x,list[id1][0].y,list[id2][1].x,list[id2][1].y);
}
}
printf("%.0lf\n",ans+eps);
}
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator