UVA10837
由唯一分解定理:
由歐拉函數定義:
因此,對於給定的,我們可以將所有符合條件的素數篩選出來,然後再枚舉選取多個即可。
但由於素數表只打到10000以內的素數,即。不過由於大於的素數至多有一個,所以在特判即可。
因爲最後一個素數的範圍爲,因此只要這個數與內的所有數互質,那麼它就是素數。
以下函數爲判斷最後一個選取的素數。
inline bool Judgt(const int& Remainder) {
//遍歷素數表,判斷最後剩下的是否爲素數
for (int i = 0; i < PrimeTable.size(); ++i) {
const int& prime = PrimeTable[i];
if (Remainder % prime == 0) {
return false;
}
if (prime * prime > Remainder) {
break;
}
}
//返回是否未選過
return Used.find(Remainder) == Used.end();
}
完整代碼:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
#include <unordered_set>
using namespace std;
int m;
bool IsNotPrime[10001];
vector<int> PrimeTable;
vector<int> Candidates;
unordered_set<int> Used;
void InitPrimeTable() {
for (int i = 2; i <= 10000; ++i) {
if (IsNotPrime[i] == false) {
PrimeTable.push_back(i);
for (int j = i * i; j <= 10000; j += i) {
IsNotPrime[j] = true;
}
}
}
}
void InitCandidates() {
for (int i = 0; i < PrimeTable.size(); ++i) {
const int& prime = PrimeTable[i];
if (m % (prime - 1) == 0) {
Candidates.push_back(prime);
}
if ((prime - 1) * (prime - 1) > m) {
break;
}
}
}
int Ans;
inline bool Judgt(const int& Remainder) {
for (int i = 0; i < PrimeTable.size(); ++i) {
const int& prime = PrimeTable[i];
if (Remainder % prime == 0) {
return false;
}
if (prime * prime > Remainder) {
break;
}
}
return Used.find(Remainder) == Used.end();
}
void DFS(int Index = 0, int Remainder = m, int n = 1) {
if (Index == Candidates.size()) {
if (Remainder == 1) {
Ans = min(Ans, n);
}
else if (Judgt(Remainder + 1)) {
n *= (Remainder + 1);
Ans = min(Ans, n);
}
return;
}
DFS(Index + 1, Remainder, n);
const int& CurPrime = Candidates[Index];
if (Remainder % (CurPrime - 1)) {
return;
}
Used.insert(CurPrime);
Remainder /= (CurPrime - 1);
n *= CurPrime;
DFS(Index + 1, Remainder, n);
while (Remainder % CurPrime == 0) {
Remainder /= CurPrime;
n *= CurPrime;
DFS(Index + 1, Remainder, n);
}
Used.erase(CurPrime);
}
void InitData() {
Ans = 200000000;
Candidates.clear();
Used.clear();
}
int main() {
InitPrimeTable();
int Case = 0;
while (~scanf("%d", &m) && m) {
InitData();
InitCandidates();
DFS();
printf("Case %d: %d %d\n", ++Case, m, Ans);
}
return 0;
}