题目:一个平面上有n个点,问会不会有一条线段穿过的点数占到总点数的x(0<x<1,小数点后一位)以上。也就是问会不会有一条线段能穿过>=m个点。
思路:从n个点里随机拿两个点,当成直线穿过的点,暴力查询这条直线经过多少个点。我是随机拿一千次判断的,之所以可以随机处理,因为直线上点数是比较多的,选不到上面的点的概率几乎为0了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define eps 1e-8
const int maxn=1e4+10;
struct node{
ll x,y;
}a[maxn];
int t,n,m;
double x;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%lf",&n,&x);
int m=(int)(n*x);
if(1.0*m+eps<1.0*n*x)
m++;
for(int i=0;i<n;i++)
scanf("%lld%lld",&a[i].x,&a[i].y);
int flag=0,k=0;
while(k<=1000)
{
int l=rand()%n;
int r=(l+rand()%n)%n;
if(a[l].x==a[r].x&&a[l].y==a[r].y) continue;
k++;
int num=0;
for(int i=0;i<n;i++)
{
if((a[l].y-a[i].y)*(a[r].x-a[i].x)==(a[r].y-a[i].y)*(a[l].x-a[i].x))
num++;
}
if(num>=m) flag=1;
if(flag) break;
}
if(flag) puts("Yes");
else puts("No");
}
return 0;
}