题目其实稍微注意一下就知道怎么搞了。
重心+凸包!
然后枚举相邻凸点就行
#include <iostream>
#include <algorithm>
using namespace std;
#define N 50005
/*==================================================*/
| Graham 求凸包 O(N * logN)
| CALL: nr = graham(pnt, int n, res); res[]为凸包点集;
/*==================================================*/
struct point { double x, y; };
bool mult(point sp, point ep, point op){
return (sp.x - op.x) * (ep.y - op.y)
>= (ep.x - op.x) * (sp.y - op.y);
}
bool operator < (const point &l, const point &r){
return l.y < r.y || (l.y == r.y && l.x < r.x);
}
int graham(point pnt[], int n, point res[]){
int i, len, k = 0, top = 1;
sort(pnt, pnt + n);
if (n == 0) return 0; res[0] = pnt[0];
if (n == 1) return 1; res[1] = pnt[1];
if (n == 2) return 2; res[2] = pnt[2];
for (i = 2; i < n; i++) {
while (top && mult(pnt[i], res[top], res[top-1]))
top--;
res[++top] = pnt[i];
}
len = top; res[++top] = pnt[n - 2];
for (i = n - 3; i >= 0; i--) {
while (top!=len && mult(pnt[i], res[top],
res[top-1])) top--;
res[++top] = pnt[i];
}
return top; // 返回凸包中点的个数
}
/*==================================================*/
| 求多边形重心
| INIT: pnt[]已按顺时针(或逆时针)排好序;
| CALL: res = bcenter(pnt, n);
/*==================================================*/
point bcenter(point pnt[], int n){
point p, s;
double tp, area = 0, tpx = 0, tpy = 0;
p.x = pnt[0].x; p.y = pnt[0].y;
for (int i = 1; i <= n; ++i) { // point: 0 ~ n-1
s.x = pnt[(i == n) ? 0 : i].x;
s.y = pnt[(i == n) ? 0 : i].y;
tp = (p.x * s.y - s.x * p.y); area += tp / 2;
tpx += (p.x + s.x) * tp; tpy += (p.y + s.y) * tp;
p.x = s.x; p.y = s.y;
}
s.x = tpx / (6 * area); s.y = tpy / (6 * area);
return s;
}
point pnt[N],res[N];
point core;
bool gao(int c)
{
point dir1;
dir1.x=res[c+1].x-res[c].x;
dir1.y=res[c+1].y-res[c].y;
if(dir1.x==0)
{
if( (core.y-res[c].y)*(core.y-res[c+1].y) < 0)
return true;
return false;
}
else if(dir1.y==0)
{
if( (core.x-res[c].x)*(core.x-res[c+1].x) < 0)
return true;
return false;
}
else
{
double a=dir1.x,b=dir1.y;
double k=b/a;
double cc=res[c].y-k*res[c].x;
double xx=(a*core.x-b*cc+b*core.y);
xx/=(a+b*k);
if( (xx-res[c].x)*(xx-res[c+1].x) < 0)
return true;
return false;
}
}
int main()
{
int n,i,j;
int T;
scanf("%d",&T);
while(T --)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%lf%lf",&pnt[i].x,&pnt[i].y);
core = bcenter(pnt,n);
//cout<<core.x<<" "<<core.y<<endl;
n = graham(pnt,n,res);
res[n]=res[0];
//for(i=0;i<=n;i++)
// cout<<res[i].x<<" "<<res[i].y<<endl;
//printf("%d/n",n);
int ans=0;
for(i=0;i<n;i++)
if(gao(i))
ans++;
printf("%d/n",ans);
}
return 0;
}
/*
10
4
0 0
1 0
2 2
1 2
*/