uva 10140——Prime Distance

来源:互联网 发布:网络管理和网络道德 编辑:程序博客网 时间:2024/05/04 17:49
题意:题目出的很简单,给定一个数据范围(好吧,又是给定一个范围),然后问你在这个给定的范围内,哪两个相邻素数挨的最近,哪两个最远。

思路:这破题数据量很大,如果直接打表,铁定T,我蛋疼地打过两边了,T了好几次,后来看到队友P用拉宾米勒的算法水过去了,不过到了poj哪里还是T个不停,算是擦边球,后来又wa了好几次,实在不行,也套用了米勒拉宾的模板,本以为顺风水过,谁知又T了,这题搁置了几天,中间看了题解,正解是打一个较小的素数表,然后用这个素数表去筛大的素数,注意要把下标改小,不然存不下,两次晒素数,方法和原理都一样,当时就是没想到!

code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;
const ll N=1000010;
const ll INF=0x3f3f3f3f3f;
ll p[N],len,vis[N];

void tab() //第一个素数表
{
len=0;
for (ll i=2;i<N;i++)
{
if (vis[i]) continue;
p[len++]=i;
for (ll j=i;j<N;j+=i)
vis[j]=1;
}
}
void sol(ll m,ll n) //根据第一个素数表去筛第二个素数表
{
memset(vis, 0, sizeof(vis));
for (ll i = 0; i <len; i++) {
for (ll j = (m/ p[i] + (m % p[i] != 0)) * p[i]; j <= n; j += p[i]) {
if (j / p[i] != 1)
vis[j - m] = 1;
}
}
}
int main()
{
tab();
ll m,n;
while (~scanf("%lld %lld",&m,&n))
{
sol(m,n);
ll mn=INF,mx=0,f=-1,fl=1;
ll minl,minr,maxl,maxr;
for (ll i=m;i<=n;i++)
{
if (vis[i-m]||i==1) continue;
if (f!=-1)
{
if (i-f<mn)
{
mn=i-f;
minl=f; minr=i;
}
if (i-f>mx)
{
mx=i-f;
maxl=f;maxr=i;
}
fl=0;
}
f=i;
}
if (fl) printf("There are no adjacent primes.\n");
else
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",minl,minr,maxl,maxr);
}
}
//1 2147483647

0 0
原创粉丝点击