此题不难,刚开始没思路,google一下,看到筛选两个字就马上懂了,于是开始写,刚开始是RE,于是把int都改成long long,有可能溢出- -。。后来WA,看了很久没看出来,再次google,发现了我少了个判断,就是remark,在筛选区间内的素数时,因为1前面没有素数,而我的memset会将1搞成素数,而后面都没更新,于是一直被当作是素数处理- -。。结果就悲剧了,以后做题还是要注意啊,什么边界的。。
#include <stdio.h> #include <string.h> const long long INT_MAX = 2147483647; bool isPrimer[47000]; //1~47000素数表 long long primer[4900]; //保存1~47000里面的素数 long long pn; //1~47000里面的素数个数 bool primerTmp[1000010]; //l~u 素数表 long long _max, _maxi, _maxj; long long _min, _mini, _minj; void init() { memset(isPrimer, true, sizeof(isPrimer)); isPrimer[0] = isPrimer[1] = false; for(int i = 2; i * i < 47000; i++) { if(isPrimer[i]) { for(int j = i * i; j < 47000; j += i) isPrimer[j] = false; } } pn = 0; for(long long i = 2; i < (long long)47000; i++) { if(isPrimer[i]) primer[pn++] = i; } } //#define TEST int main() { #ifdef TEST freopen("input.txt", "r", stdin); #endif init(); long long l, u; while(scanf("%lld%lld", &l, &u) == 2) { if(l == 1) l = 2; //remark; memset(primerTmp, true, sizeof(primerTmp)); for(int i = 0; i < pn && primer[i] * primer[i] <= u; i++) { long long k = l / primer[i]; if(l % primer[i] != 0) k++; if(k == 1) k++; for(; primer[i] * k <= u; k++) primerTmp[primer[i] * k - l] = false; } long long m = u - l; long long i = 0; for(; i < m; i++) if(primerTmp[i]) break; if(i == m) { printf("There are no adjacent primes./n"); continue; } _max = 0; _min = INT_MAX; for(long long j = i + 1; j <= m; j++) { if(primerTmp[j]) { long long tmp = j - i; if(_max < tmp) { _maxi = i; _maxj = j; _max = tmp; } if(_min > tmp) { _mini = i; _minj = j; _min = tmp; } i = j; } } if(_max == 0) printf("There are no adjacent primes./n"); else printf("%lld,%lld are closest, %lld,%lld are most distant./n", _mini + l, _minj + l, _maxi + l, _maxj + l); } return 0; }