UVa 10837 (欧拉函数 搜索) A Research Problem

时间:2023-03-08 20:41:20

发现自己搜索真的很弱,也许做题太少了吧。代码大部分是参考别人的,=_=||

题意:

给出一个phi(n),求最小的n

分析:

回顾一下欧拉函数的公式:UVa 10837 (欧拉函数 搜索) A Research Problem,注意这里的Pi是互不相同的素数,所以后面搜索的时候要进行标记。

先找出所有的素数p,满足(p - 1)整除题目中所给的phi(n)

然后暴搜。。

素数打表打到1e4就够了,如果最后剩下一个大素数单独进行判断。

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ;
const int INF = ; int phi_n, ans; bool vis[maxn + ];
int prime[], pcnt = ;
int fac[], tot; void prime_table()
{
int m = sqrt(maxn + 0.5);
for(int i = ; i <= m; i++) if(!vis[i])
for(int j = i * i; j <= maxn; j += i) vis[j] = true;
for(int i = ; i <= maxn; i++) if(!vis[i]) prime[pcnt++] = i;
} void factor(int n)
{
tot = ;
for(int i = ; i < pcnt && (prime[i]-) * (prime[i]-) <= n; i++) if(n % (prime[i] - ) == )
fac[tot++] = prime[i];
} int judge(int n)
{
if(n == ) return ;
n++;
//判断剩余的phin中加1后是否为素数
for(int i = ; i < pcnt && prime[i] * prime[i] <= n; i++) if(n % prime[i] == )
return -;
//如果为素数的话,判断是否标记过
for(int i = ; i < tot; i++) if(vis[i] && n == fac[i])
return -;
return n;
} void dfs(int n, int phin, int d)
{
if(d == tot)
{
int t = judge(phin);
if(t > ) ans = min(ans, n * t);
return;
} dfs(n, phin, d+);
if(phin % (fac[d] - ) == )
{
vis[d] = true;
n *= fac[d];
phin /= (fac[d] - );
for(;;)
{
dfs(n, phin, d+);
if(phin % fac[d] != )
return;
phin /= fac[d]; n *= fac[d];
}
}
vis[d] = false;
} int main()
{
freopen("in.txt", "r", stdin); int kase = ;
prime_table();
while(scanf("%d", &phi_n) == && phi_n)
{
ans = INF;
memset(vis, false, sizeof(vis));
factor(phi_n);
dfs(, phi_n, );
printf("Case %d: %d %d\n", ++kase, phi_n, ans);
} return ;
}

代码君