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.....很坑啊...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }