题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=3685
先求出重心,然后求凸包
开始的时候TLE,用的cin输入,前面加上了ios::sync_with_stdio(false)还是超时。C++真的比C慢这么多。。。
代码如下:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Point{
double x,y;
Point(){}
Point(double x,double y):x(x),y(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 p){return Vector(a.x*p,a.y*p);}
Vector operator / (Vector a,double p){return Vector(a.x/p,a.y/p);}
bool operator < (Point a,Point b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
double cross(Vector a,Vector b){return (a.x*b.y-a.y*b.x);}
double Dot(Vector a,Vector b){return (a.x*b.x+a.y*b.y);}
const double eps=1e-10;
int dcmp(double x){
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
double Length2(Vector a){
return Dot(a,a);
}
Point polygon[50010];
Point ch[50010];
bool cmp(Point a,Point b){
int d=dcmp(cross(a-polygon[0],b-polygon[0]));
return d>0||(d==0&&Length2(a-polygon[0])<Length2(b-polygon[0]));
}
Point Focus(int n){//ÖØÐÄ
double area=0;
Point s=Point(0,0);
for(int i=1;i<n-1;++i){
double a=cross(polygon[i+1]-polygon[0],polygon[i]-polygon[0]);
s.x=s.x+(polygon[0].x+polygon[i].x+polygon[i+1].x)*a;
s.y=s.y+(polygon[0].y+polygon[i].y+polygon[i+1].y)*a;
area+=a;
}
s.x=s.x/3/area;
s.y=s.y/3/area;
return s;
}
int ConvexHull(int n){//͹°ü
sort(polygon,polygon+n);
sort(polygon+1,polygon+n,cmp);
int m=0;
for(int i=0;i<n;++i){
while(m>1&&cross(ch[m-1]-ch[m-2],polygon[i]-ch[m-2])<=0)m--;
ch[m++]=polygon[i];
}
return m;
}
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
// cin>>T;
scanf("%d",&T);
while(T--){
int n;
// cin>>n;
scanf("%d",&n);
for(int i=0;i<n;++i){
// cin>>polygon[i].x>>polygon[i].y;
scanf("%lf%lf",&polygon[i].x,&polygon[i].y);
}
Point F=Focus(n);
n=ConvexHull(n);
ch[n]=ch[0];
n++;
int ans=0;
for(int i=0;i<n-1;++i){
if(Dot(F-ch[i],ch[i+1]-ch[i])>0&&Dot(F-ch[i+1],ch[i]-ch[i+1])>0)ans++;
}
cout<<ans<<endl;
}
return 0;
}
在求凸包的函数中,用训练指南中刘汝佳给出的代码,更快一些。
如下:
int ConvexHull(int n){//凸包
sort(polygon,polygon+n);
// sort(polygon+1,polygon+n,cmp);
int m=0;
for(int i=0;i<n;++i){
while(m>1&&cross(ch[m-1]-ch[m-2],polygon[i]-ch[m-2])<=0)m--;
ch[m++]=polygon[i];
}
int k=m;
for(int i=n-2;i>=0;--i){
while(m>k&&cross(ch[m-1]-ch[m-2],polygon[i]-ch[m-2])<=0)m--;
ch[m++]=polygon[i];
}
if(n>1)m--;
return m;
}