- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- using namespace std;
- const int maxn = 100000 + 10;
- int prime[maxn+1];
- void getprime()
- {
- memset(prime, 0, sizeof(prime));
- for (int i = 2; i <= maxn; i++)
- {
- if (!prime[i])prime[++prime[0]] = i;
- for (int j = 1; j <= prime[0] && prime[j] <= maxn / i; j++)
- {
- prime[prime[j] * i] = 1;//标记不是素数
- if (i%prime[j] == 0)break;
- }
- }
- }
- bool notprime[1000000 + 10];
- int prime2[1000000 + 10];
- void getprime2(int L, int R)//筛选[L,R]区间的素数
- {
- memset(notprime, false, sizeof(notprime));
- if (L < 2)L = 2;
- for (int i = 1; i <= prime[0] && (long long)prime[i] * prime[i] <= R; i++)
- {
- int s = L / prime[i] + (L % prime[i] > 0);//(s==prime[i]-1||s==prime[i])
- if (s == 1)s = 2;//s==1说明除尽 L本身不是素数所有从2开始累乘
- for (int j = s; (long long)j*prime[i] <= R; j++)
- {
- if ((long long)j*prime[i] >= L) {
- notprime[j*prime[i]-L] = true;//不是素数
- }
- }
- }
- prime2[0] = 0;//prime[0]用来存放素数的个数
- for (int i = 0; i <= R - L; i++) {
- if (!notprime[i]) {
- prime2[++prime2[0]] = i + L;//计数和向后打表
- }
- }
- }
- int main()
- {
- getprime();
- int L, R;
- while (scanf("%d%d", &L, &R) == 2)
- {
- getprime2(L, R);
- if (prime2[0] < 2)printf("There are no adjacent primes.\n");
- else
- {
- int x1 = 0, x2 = 100000000, y1 = 0, y2 = 0;
- for (int i = 1; i < prime2[0]; i++)
- {
- if (prime2[i + 1] - prime2[i] < x2 - x1) {
- x1 = prime2[i]; x2 = prime2[i + 1];
- }
- if (prime2[i + 1] - prime2[i] > y2 - y1) {
- y1 = prime2[i]; y2 = prime2[i + 1];
- }
- }
- printf("%d,%d are closest, %d,%d are most distant.\n", x1, x2, y1, y2);
- }
- }
- return 0;
- }
单纯记录一下这种素数打表的想法