解题思路
题意大概就是一个可以旋转的半圆,停止时能覆盖最多多少点。
先把那些肯定无法被覆盖的排掉,然后每次以一个点与中点组成一个直线,再枚举其他点,用叉积判断在直线上方还是下方,在这条直线上边的 m 1 + + m1++ m1++,在下边的 m 2 + + m2++ m2++,在直线上的 s + + s++ s++,完后比较 m 1 + s m1+s m1+s与 m a x max max的大小和 b + m 2 b+m2 b+m2与 m a x max max的大小 。
代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
ll x,y,n,m1,m2,m3,ans,v[100010],a[100010],b[100010];
double r;
int main() {
while(scanf("%lld%lld%lf",&x,&y,&r)) {
memset(v,0,sizeof(v));
if(r<0)return 0;
scanf("%lld",&n);
for(int i=1; i<=n; i++) {
scanf("%lld%lld",&a[i],&b[i]);
double t=sqrt((a[i]-x)*(a[i]-x)+(b[i]-y)*(b[i]-y));
if(t>r)
v[i]=1;
}
ans=0;
for(int i=1; i<=n; i++) {
if(v[i])continue;
m1=m2=m3=0;
for(int j=1; j<=n; j++) {
if(v[j])continue;
ll k=(a[i]-x)*(b[j]-y)-(b[i]-y)*(a[j]-x);
if(k<0)m1++;
if(k>0)m2++;
if(k==0)m3++;
}
ans=max(ans,max(m1,m2)+m3);
}
printf("%lld\n",ans);
}
}