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;
}