您的位置:首页 > 其它

ZOJ-1842

2014-06-08 14:59 302 查看
核心算法就是素数测试,本题用那种朴素的遍历测是否含因子的暴力算法肯定是TLE的。。必须用筛法或随机算法。。由于筛法不会,只能看着算法导论上的随机算法写了一遍,原理还不是很理解。。现成的算法还是调了很久。。中间各种溢出的错误忽略了处理,那种最大整数的测试数据一运行程序就挂了。。各种坑,数论这一块太弱了

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

static int modular_exponentiation(int a, int b, int n)
{
int rb = 0;
int k = 0;
while (b)
{
rb <<= 1;
rb |= b & 1;
b >>= 1;
k++;
}
int i;
long long d = 1;
for (i = 0; i < k; i++)
{
d = (d * d) % n;
if (rb & 1)
d = (d * a) % n;
rb >>= 1;
}
return d;
}

static int witness(int a, int n)
{
int u = n - 1;
int t = 0;
while (!(u & 1))
{
u >>= 1;
t++;
}
int i;
long long now, prev = modular_exponentiation(a, u, n);
for (i = 0; i < t; i++)
{
now = (prev * prev) % n;
if (now == 1 && prev != 1 && prev != n - 1)
return 1;
prev = now;
}
if (now != 1)
return 1;
return 0;
}

static int miller_rabin(int n)
{
if (n == 2)
return 1;
else if (n == 1 || (n & 1) == 0)
return 0;

int j;
int a;
for (j = 0; j < 10; j++)
{
a = rand() % (n - 1) + 1;
if (witness(a, n))
return 0;
}
return 1;
}

int main()
{
int U, L;
while (scanf("%d %d", &U, &L) != EOF)
{
long long i;
int is_first = 1, prev, pa = 0, pb, pc, pd, mind = INT_MAX, maxd = 0;
for (i = U; i <= L; i++)
if (miller_rabin(i))
{
if (is_first)
is_first = 0;
else
{
if (i - prev < mind)
{
pa = prev;
pb = i;
mind = i - prev;
}
if (i - prev > maxd)
{
pc = prev;
pd = i;
maxd = i - prev;
}
}
prev = i;
}
if (pa)
printf("%d,%d are closest, %d,%d are most distant.\n", pa, pb, pc,
pd);
else
puts("There are no adjacent primes.");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: