版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leekerian/article/details/89076517
随机化算法,每次随机取两个点那么两个点刚好在所求的直线上的概率为k^2,带入1-(1-k^2)^n公式循环1000次左右就能马上逼近1
#include <iostream>
#include <cmath>
#include <cstdio>
#include <time.h>
using namespace std;
const double eps=1e-8;
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
else return 1;
}
struct Point{
double x,y;
Point(double _x,double _y){x=_x,y=_y;}
Point(){}
double operator ^(const Point &b)const
{
return x*b.y-y*b.x;
}
Point operator -(const Point &b)const
{
return Point(x-b.x,y-b.y);
}
};
Point p[111111];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
double k;
scanf("%d%lf",&n,&k);
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
int fg=0;
srand(time(0));
for(int i=0;i<1111;i++)
{
int a=rand()%n;
int b=rand()%n;
if(a==b) continue;
int n1=0;
for(int j=0;j<n;j++)
{
if(j==a||j==b) continue;
if(sgn((p[a]-p[j])^(p[b]-p[j]))==0)
n1++;
}
double k1=(n1*1.0+2.0)/(n*1.0);
if(sgn(k1-k)>=0)
{
fg=1;
break;
}
}
if(fg) printf("Yes\n");
else printf("No\n");
}
return 0;
}