我疯了, 边界问题超级不想处理了, 整整耗了我一天时间在找资料, 调试, 各种调试调试。。。。。
附上AC 纪念下边界问题。
大家最好不要看源码, 这种题, 思路简单, 看个人能力了,
不会的最好多花时间调试, 太 @%*Y$浪费时间就是。
侧面反映出我还是太弱了, 加油吧。↖(^ω^)↗
额。。。 C语言写的。
= = 素数表, 二次筛选,,,,,学来的。 感谢http://hi.baidu.com/rain_bow_joy/blog/item/0aced9c7cda12d119d163d18.html
谁能告诉我为什么用sqrt(50000)就错?? 感谢各位了
#include <stdio.h>
#include <math.h>
#include <string.h>
#define INF 2147483647
__int64 prime[50000], visit[50000], n;
__int64 reprime[1000010], len;
void Prime()
{
__int64 i, j;
memset(prime, 0, sizeof(prime));
memset(visit, 0, sizeof(visit));
n = 0;
//不能用k = sqrt(50000),绝对不能! 疯了!!!
for (i = 2; i <= 50000; i++)
{
if (visit[i] == 0)
{
prime[n++] = i;
for (j = 2 * i; j <= 50000; j += i)
visit[j] = 1;
}
}
}
void Reprime(__int64 l, __int64 r)
{
__int64 i, begin;
len = 0;
memset(reprime, 0, sizeof(reprime));
//下界问题 1, 2
if (l == 1)
reprime[0] = 1;
for (i = 0; i < n && prime[i] * prime[i] <= r; i++)
{
begin = l / prime[i] + (l % prime[i] > 0);
if (begin == 1)
begin++;
for (begin *= prime[i]; begin <= r; begin += prime[i])
reprime[begin - l] = 1;
}
}
int main()
{
__int64 L, U, i, previous;
__int64 min, min_l, min_r, max, max_l, max_r;
Prime();
while (scanf("%I64d%I64d", &L, &U) != EOF)
{
Reprime(L, U);
len = 0;
min = INF; max = -INF;
//找到第一个素数, 用上这个能提高15ms, 不用总时间是125ms
i = L;
while (reprime[i-L]) { i++; }
previous = i - L - 1;
//i=L;
for (i = L; i <= U; i++)
{
if (reprime[i-L] == 0)
{
len++;
//下界问题,找到第一个素数
if (len != 1)
{
if (min > (i - previous))
{
min = i - previous;
min_l = previous;
min_r = i;
}
if (max < (i - previous))
{
max = i - previous;
max_l = previous;
max_r = i;
}
}
previous = i;
}
}
if(len <= 1)
printf("There are no adjacent primes.\n");
else
printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n", min_l, min_r, max_l, max_r);
}
return 0;
}