Wannafly Union Goodbye 2016-A//初识随机化~

  想来想去还是把这个题写下来了。自己在补题遇到了许多问题。

  给出n(n<=1e5)个点,求是否存在多于p(p>=20)×n/100的点在一条直线上...

  时限20s,多组数据,暴力至少n^2。考虑p>=20.所以我们可以随机点 一次随机到在存在的直线上的点的概率至少是1/5。

那么随机两个点确定一条直线,成功率为1/25,失败率为24/25;我们随机个x次 失败的概率为(24/25)^x。

x选的越大,成功可能就越高。我们随机个200次好了...其实内心觉得20次都多...

  遇到的问题:时间种子多次清空...导致随机情况相同....没理解随机的实现..

极限情况点数<=2.....很坑啊...

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stdio.h>
 4 #include <time.h>
 5 #include <math.h>
 6 using namespace std;
 7 typedef long long ll;
 8 const int N = 1e5+10;
 9 ll x[N],y[N];
10 bool judge(int n,int pp)
11 {
12     int p=rand()%n;
13     int q=rand()%n;
14     if(p==q) return false;
15     ll px = x[p]-x[q];
16     ll py = y[p]-y[q];
17     //px/dx = py/dy;
18     //px*dy = py*dx
19     //cout<<"PQ"<<p<<q<<cnt<<endl;
20     //cout<<px<<"  "<<py<<endl;
21     int ans = 2;
22     for(int i=0;i<n;i++)
23     {
24         ll dx = (x[i]-x[q]);
25         ll dy = (y[i]-y[q]);
26         //cout<<dx<<"  "<<dy<<endl;
27         if(i==p||i==q) continue;
28         if(px*dy==py*dx) ans++;
29     }
30    // cout<<ans<<endl;
31     return ans*100>=pp*n;
32 }
33 int main()
34 {
35     srand(time(NULL));
36     int n,p;
37     while(scanf("%d%d",&n,&p)!=EOF)
38     {
39 
40         for(int i=0;i<n;i++)
41         {
42             scanf("%lld%lld",x+i,y+i);
43         }
44         bool mk = false;
45         for(int i=0;i<200;i++) if(judge(n,p)) mk = true;
46         if(n<=2) mk = true;
47         if(mk) puts("possible");
48         else puts("impossible");
49     }
50     return 0;
51 }
神奇的随机化~
原文地址:https://www.cnblogs.com/Geek-xiyang/p/6275680.html