您的位置:首页 > 其它

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

2015-02-24 14:56 309 查看
发现自己搜索真的很弱,也许做题太少了吧。代码大部分是参考别人的,=_=||

题意:

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

分析:

回顾一下欧拉函数的公式:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 10000;
const int INF = 200000000;

int phi_n, ans;

bool vis[maxn + 10];
int prime[1500], pcnt = 0;
int fac[1500], tot;

void prime_table()
{
int m = sqrt(maxn + 0.5);
for(int i = 2; i <= m; i++) if(!vis[i])
for(int j = i * i; j <= maxn; j += i) vis[j] = true;
for(int i = 2; i <= maxn; i++) if(!vis[i]) prime[pcnt++] = i;
}

void factor(int n)
{
tot = 0;
for(int i = 0; i < pcnt && (prime[i]-1) * (prime[i]-1) <= n; i++) if(n % (prime[i] - 1) == 0)
fac[tot++] = prime[i];
}

int judge(int n)
{
if(n == 1) return 1;
n++;
//判断剩余的phin中加1后是否为素数
for(int i = 0; i < pcnt && prime[i] * prime[i] <= n; i++) if(n % prime[i] == 0)
return -1;
//如果为素数的话,判断是否标记过
for(int i = 0; i < tot; i++) if(vis[i] && n == fac[i])
return -1;
return n;
}

void dfs(int n, int phin, int d)
{
if(d == tot)
{
int t = judge(phin);
if(t > 0) ans = min(ans, n * t);
return;
}

dfs(n, phin, d+1);
if(phin % (fac[d] - 1) == 0)
{
vis[d] = true;
n *= fac[d];
phin /= (fac[d] - 1);
for(;;)
{
dfs(n, phin, d+1);
if(phin % fac[d] != 0)
return;
phin /= fac[d]; n *= fac[d];
}
}
vis[d] = false;
}

int main()
{
freopen("in.txt", "r", stdin);

int kase = 0;
prime_table();
while(scanf("%d", &phi_n) == 1 && phi_n)
{
ans = INF;
memset(vis, false, sizeof(vis));
factor(phi_n);
dfs(1, phi_n, 0);
printf("Case %d: %d %d\n", ++kase, phi_n, ans);
}

return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: