題意:
給你n個點,問你有沒有一條直線,經過這n個點裏的m個點,使得m/n>=x,
解析:
從1...n裏面隨機(rand()%n+1)取兩個點,那麼直線就確定了,
然後再掃一遍n個點,計算這條直線的貢獻,如果滿足條件則輸出Yes
這個過程好像只要隨機250次就能在1e4個點中找到答案,好像有些隨機1000次的也能在5s之內過
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
typedef pair<ll,ll> PLL;
const int N = 1e4+10;
PLL f[N];
int cross(PLL x,PLL y)
{
return x.fi*y.se-x.se*y.fi;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
double x;
scanf("%d%lf",&n,&x);
int jie=ceil(n*x);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&f[i].fi,&f[i].se);
}
int flag=0;
for(int i=0;i<250;i++)
{
int a=rand()%n+1;
int b=rand()%n+1;
if(f[a].fi==f[b].fi&&f[a].se==f[b].se)
{
continue;
}
int sum=2;
PLL now;
now.fi=f[a].fi-f[b].fi;
now.se=f[a].se-f[b].se;
for(int j=1;j<=n;j++)
{
if(j==a||j==b) continue;
PLL nex;
nex.fi=f[a].fi-f[j].fi;
nex.se=f[a].se-f[j].se;
if(cross(now,nex)==0) sum++;
}
if(sum>=jie) {flag=1;break;}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}