自己想了一个方法判断点是不是在凸包内,先求出凸包面积,在求由点与凸包上每两个点之间的面积(点已经排好序了),如果两者相等,则点在凸包内,否则不在(时间复杂度可能有点高)但是这题能过
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-7; const int N=100+10,maxn=500+100,inf=0x3f3f3f; struct point{ double x,y; }; point p[N],s[N][N]; int n,top[N]; bool vis[N]; inline bool zero(double x) { return fabs(x)<eps; } double dis(point p1,point p2) { return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } double dir(point p1,point p2,point p3) { return (p3.x-p1.x)*(p2.y-p1.y)-(p3.y-p1.y)*(p2.x-p1.x); } bool comp(point p1,point p2) { double te=dir(p[0],p1,p2); if(te<0)return 1; if(zero(te)&&dis(p[0],p1)<dis(p[0],p2))return 1; return 0; } void Graham(int k) { int pos; double minx=inf,miny=inf; for(int i=0;i<n;i++) { if(p[i].x<minx||(p[i].x==minx&&p[i].y<miny)) { minx=p[i].x; miny=p[i].y; pos=i; } } swap(p[0],p[pos]); sort(p+1,p+n,comp); p[n]=p[0]; s[k][0]=p[0],s[k][1]=p[1], s[k][2]=p[2]; top[k]=2; for(int i=3;i<=n;i++) { while(top[k]>=2&&dir(s[k][top[k]-1],s[k][top[k]],p[i])>=0)top[k]--; s[k][++top[k]]=p[i]; } } double square(int k) { double ans=0; for(int i=0;i<top[k]-1;i++) ans-=dir(s[k][0],s[k][i],s[k][i+1]); return ans/2; } bool inside(double sq,double x,double y,int k) { double ans=0; point p0;p0.x=x,p0.y=y; for(int i=0;i<top[k];i++) { if(dir(p0,s[k][i],s[k][i+1])<0)ans-=dir(p0,s[k][i],s[k][i+1]); else ans+=dir(p0,s[k][i],s[k][i+1]); } return sq*2==ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); int cnt=0; while(cin>>n,n!=-1){ for(int i=0;i<n;i++) cin>>p[i].x>>p[i].y; Graham(cnt); cnt++; } /* for(int i=0;i<cnt;i++) { for(int j=0;j<top[i];j++) cout<<s[i][j].x<<" "<<s[i][j].y<<endl; }*/ memset(vis,0,sizeof vis); int x,y; double ans=0; while(cin>>x>>y){ for(int i=0;i<cnt;i++) { double sq=square(i); if(!vis[i]&&inside(sq,x,y,i)) { vis[i]=1; ans+=sq; break; } } } cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans<<endl; return 0; } /********************* *********************/