https://vjudge.net/problem/Gym-101482F
思路:給出個點的座標,問是否存在一條直線,使得至少有的點位於該條直線上。
思路:枚舉?肯定會。我們假設最有個點位於一條直線上,每次任意選擇兩個點,選擇到它們中的個點的概率是,化簡可得,由於最少取,所以上述概率最低約爲,這給了我們啓發:每次隨機選取兩個點,選取次,那麼得到的結果是正確的概率就高達,顯然可以取的很大,所以結果很有可能是正確的。計算就不用多說了,注意用乘法不要用除法。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pr pair<int,int>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,p;
ll x[maxn],y[maxn];
ll bx1,by1,bx2,by2;
bool check(ll dx,ll dy)
{
ll r1=(by2-by1)*(dx-bx2);
ll r2=(bx2-bx1)*(dy-by2);
return r1==r2;
}
int main()
{
srand(time(nullptr));
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++)
scanf("%lld %lld",&x[i],&y[i]);
if(n<=2)
printf("possible\n");
else
{
int t=1000,id1,id2,ct;
bool flag=0;
int res=ceil(n*p*1.0/100);
while(t--&&!flag)
{
id1=(ll)rand()*rand()%n+1;
id2=(ll)rand()*rand()%n+1;
while(id2==id1)
id2=rand()%n+1;
bx1=x[id1],by1=y[id1];
bx2=x[id2],by2=y[id2];
ct=2;
for(int i=1;i<=n;i++)
if(i!=id1&&i!=id2)
ct+=check(x[i],y[i]);
if(ct>=res)
flag=1;
}
printf("%s\n",flag?"possible":"impossible");
}
return 0;
}