數論_質數_POJ2689_Prime Distance
阿新 • • 發佈:2018-11-29
思路分析:
根據合數N的最小的質因數在區間[2, ], 因此可篩法求出[2, ]上所有的素數, 對於該範圍內的每個素數p, 標記[L, U]上為不等於p且為p的倍數的所有的整數, 最終未被標記的就是[L, R]上的素數. 下面給出基於此策略的AC程式碼: (注意第27行為防止數值超過int型的最大值而使用了long long)
//POJ2689_Prime Distance #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> using namespace std; const int MAX = 1e6 + 5, INF = 0x3f3f3f3f; //ok[i]為0表示L + i - 1為素數, 為1則L + i - 1為合數, prim[i]為1表示i為素數, 為2表示i為合數 int L, U, ok[MAX + 5], prim[MAX + 5]; int main(){ //篩法求1...MAX之間的素數 for(int i = 2; i <= MAX; ++i){ if(prim[i]) continue; prim[i] = 1; for(int j = i; j <= MAX / i; ++j) prim[i * j] = 2; } while(~scanf("%d %d", &L, &U)){ int su = sqrt((double)U); //標記L, U之間的所有素數 memset(ok, 0, sizeof(ok)); for(int i = 2; i <= su; ++i) if(prim[i] == 1) for(int j = L / i + (bool)(L % i); j <= U / i; ++j) if(j > 1) ok[j * i + 1 - L] = 1; vector<int> prvec;//儲存L...U之間所有的素數 for(long long i = 1, j = L; j <= U; ++i, ++j) if(!ok[i] && j >= 2) prvec.push_back(j); if(prvec.size() <= 1) cout << "There are no adjacent primes." << endl; else{ int mindis = INF, minpos, maxdis = -INF, maxpos; for(int i = 0; i < prvec.size() - 1; ++i){ int y = prvec[i + 1] - prvec[i]; if(y < mindis) mindis = y, minpos = i; if(y > maxdis) maxdis = y, maxpos = i; } cout << prvec[minpos] << "," << prvec[minpos + 1] << " are closest, " << prvec[maxpos] << "," << prvec[maxpos + 1] << " are most distant." << endl; } } return 0; }