随机化算法优化时间复杂度
两点连成一线,遍历n-2个点是否在线上,随机抽取1000组,组数越多误差越小。
#include<bits/stdc++.h>
using namespace std;
int main()
{
double n,p;
int i,j,l,k;
pair<double,double>a[100010];
while(~scanf("%lf%lf",&n,&p))
{
p=ceil(p/100.0*n);//向上去整,求最小所需点数目
for(i=0; i<n; i++)
scanf("%lf%lf",&a[i].first,&a[i].second);
int sum=0;
//优化1
if(n<=2) {printf("possible\n");continue;}
//优化1
srand(time(0));
//优化2
for(k=0; k<1000; k++)
{
i=rand()%(int)n;
j=rand()%(int)n;
while(j==i)
j=rand()%(int)n;
//优化2
sum=2;
for(l=0; l<=n-1; l++)
{
if(l==i||l==j)
continue;
if((a[i].first-a[j].first)*(a[l].second-a[j].second)-(a[i].second-a[j].second)*(a[l].first-a[j].first)==0)
sum++;
if(sum>=p)
break;
}
if(sum>=p)
break;
}
if(sum>=p)
printf("possible\n");
else
printf("impossible\n");
}
}
相同思想参考,费马检测(用于判定一个数是否是素数,不可用于打表)
费马小定理
假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
威尔逊定理
当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )
#include<bits/stdc++.h>
using namespace std;
typedef long long ll
using namespace std;
ll Quick_Mod(ll a, ll b, ll mod)//快速幂
{
ll res = 1,term = a % mod;
while(b)
{
if(b & 1) res = (res * term) % mod;
term = (term * term) % mod;
b >>= 1;
}
return res;
}
//费马检测
bool Is_Prime(ll n)
{
int i;
srand(time(0));
for(i = 0;i < 5;i++)//随机次数
if(Quick_Mod(1+rand()%(n-1) ,n - 1,n) != 1)
break;
if(i == 5) return true;
return false;
}