hunnu11550:欧拉函数

Problem description
  一个数x的欧拉函数Φ(x)定义为全部小于x的正整数中与x互质的数的数目,如小于5且和5互质的数有1、2、3、4,一共4个,故Φ(5)=4。

对于随意正整数x,我们定义两种操作: 
1、f(x) = x + Φ(x);
2、g(x) = x * Φ(x);

如今,给定一个数a,问从1開始,须要多少步操作能得到a。
(如,当a = 2时,f(1)即为所求,故答案为1。而当a = 3时,f(f(1))即为所求。故答案为2) 

Input
  每行输入一个整数a(0<a<=100000)。 
Output
  输出须要的步数,假设无法得到,输出-1。
Sample Input
2
3
Sample Output
1
2
Problem Source
  HUNNU Contest 

打出函数表,然后搜索便能够了


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
#include <time.h>
using namespace std;

#define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 100000
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8

int oula[N+5];
int ans[N+5];
void bfs()
{
    int i,j,k;
    queue<int> Q;
    for(i = 1;i<=N;i++)
    {
        oula[i]=i;
        ans[i] = INF;
    }
    for(i = 2;i<=N;i++)
    {
        if(i==oula[i])
        {
            for(j = 1;j*i<=N;j++)
            {
                oula[j*i] = (oula[j*i]/i)*(i-1);
            }
        }
    }
    ans[1] = 0;
    Q.push(1);
    while(!Q.empty())
    {
        int s = Q.front();
        Q.pop();
        if(s+oula[s]<=N&&ans[s+oula[s]]>ans[s]+1)
        {
            ans[s+oula[s]]=ans[s]+1;
            Q.push(s+oula[s]);
        }
        if((LL)s*oula[s]>N) continue;
        if((LL)s*oula[s]<=N&&ans[s*oula[s]]>ans[s]+1)
        {
            ans[s*oula[s]]=ans[s]+1;
            Q.push(s*oula[s]);
        }
    }
}

int main()
{
    LL i,j,k;
    int n;
    bfs();
    while(~scanf("%d",&n))
    {
        if(ans[n]==INF) puts("-1");
        else
        printf("%d\n",ans[n]);
    }

    return 0;
}


posted @ 2017-07-01 09:51  zhchoutai  阅读(194)  评论(0编辑  收藏  举报