POJ 2689 数论

我疯了, 边界问题超级不想处理了, 整整耗了我一天时间在找资料, 调试, 各种调试调试。。。。。

附上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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值