Acwing 196. 质数距离
练习题:
AcWing 197. 阶乘分解
扩展知识:
任何一个合数都存在一个质因子小于等于
n
\sqrt{n}
n
求一个数n除以一个数向上取整的方法:
⌈
L
P
⌉
×
P
=
⌈
L
+
R
+
1
P
⌉
×
P
\lceil \frac{L}{P} \rceil \times P = \lceil \frac{L+R+1}{P}\rceil \times P
⌈PL⌉×P=⌈PL+R+1⌉×P
思路:
该题按照前面的知识就变得简单了。
看这个数据范围:
说明我们可以每次可以进行最多进行50000个数据的质数判断。
然后将该范围内的所有的合数筛选掉,那么剩下的就是质数,然后将剩下的质数储存下来,然进行扫描,找到最大的数。
注意:
质数的分布不是越大越稀疏。,例如:7 13 17,13 - 7 = 6,17 - 13 = 4;
所以说要扫描。
代码实现
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int N = 1000006;
int primes[N];
bool used[N];
int idx = 0;
// 素数筛
void get_prime(int x)
{
idx = 0;
memset(used,false,sizeof(used));
for(int i = 2; i <= x; i++)
{
if(!used[i]) primes[++idx] = i;
for(int j = 1; i * primes[j] <= x; j++)
{
used[i * primes[j]] = true;
if(i % primes[j] == 0) break;
}
}
}
signed main (void)
{
int l,r;
while(cin >> l >> r)
{
get_prime(50000);
memset(used,false,sizeof(used));
for(int j = 1; j <= idx; j++)
{
int p = primes[j];
for(int i = max((l + p - 1)/p * p,2 * p); i <= r; i += p) // (l+p-1)/p*p 是为了找大于l的且是p的倍数的最小值,2*p是为了放置把质数p自己筛掉
{
used[i - l] = true;
}
}
idx = 0;
// 找r到l之间的所有质数。
for(int i = 0; i <= r - l; i++)
{
if(!used[i] && i + l > 1)
{
primes[++idx] = l + i;
}
}
if(idx < 2)
{
printf("There are no adjacent primes.\n");
continue;
}
int maxx = 1,minn = 1,minp,maxp;
int minans = 0x7fffffff,maxans = 0;
// 扫描查找最大最小值
for(int i = 1; i < idx; i++)
{
if(primes[i + 1] - primes[i] > maxans) maxans = primes[i+1] - primes[i],maxp = i;
if(primes[i + 1] - primes[i] < minans) minans = primes[i+1] - primes[i],minp = i;
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",primes[minp],primes[minp+1],primes[maxp],primes[maxp+1]);
}
return 0;
}