2011年大连ACM网络赛 hdu 4002 Find the maximum

Find the maximum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 276    Accepted Submission(s): 141


Problem Description
Euler's Totient function, φ (n) [sometimes called the phi function], is used to determine the number of numbers less than n which are relatively prime to n . For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6. 
HG is the master of X Y. One day HG wants to teachers XY something about Euler's Totient function by a mathematic game. That is HG gives a positive integer N and XY tells his master the value of 2<=n<=N for which φ(n) is a maximum. Soon HG finds that this seems a little easy for XY who is a primer of Lupus, because XY gives the right answer very fast by a small program. So HG makes some changes. For this time XY will tells him the value of 2<=n<=N for which n/φ(n) is a maximum. This time XY meets some difficult because he has no enough knowledge to solve this problem. Now he needs your help.
 

Input
There are T test cases (1<=T<=50000). For each test case, standard input contains a line with 2 ≤ n ≤ 10^100.
 

Output
For each test case there should be single line of output answering the question posed above.
 

Sample Input
  
  
2 10 100
 

Sample Output
  
  
6 30
Hint
If the maximum is achieved more than once, we might pick the smallest such n.  
 

Source
 

Recommend
lcy
 

Statistic |  Submit |  Discuss |  Note
题意:

寻找 1-n中  n/φ (n) 的最大值 其中 φ (n)为欧拉函数

分析:

我遇到这个题首先看到数据量10^100,就觉得这题可能有规律,于是写了一个c++程序打了一个表看了一下


#include <iostream>

#include <algorithm>

#include <cstring>

#include <cstdio>

#include <queue>

#include <stack>

#include <cctype>

#include <cmath>

#include <set>

#include <sstream>

#include <fstream>

using namespace std;

#define inf (1<<30)

__int64 a[1001001];

void all()

{

    __int64 i,j;

    for(i=1;i<=1001000;i++)

    a[i]=i;

    for(i=2;i<=1001000;i++)

    {

       if(a[i]==i)

       {

           for(j=1;j*i<=1001000;j++)

           a[i*j]=a[i*j]/i*(i-1);

       }

    }

}

ofstream fout("c:\ii.out");

int main()

{

    double M=0;

    int i,j,k;

    int n,ans;

    all();

    for(j=1;j<100;j++)

    {



        n=j;

        ans=0;

        M=0;

        for(i=0;i<=n;i++)

        {

            if(M<((double)i/(double)a[i]))

            {

                M=((double)i/(double)a[i]);

                ans=i;

            }

        }

        cout<<n<<" "<<ans<<endl;

        fout<<n<<" "<<ans<<endl;

    }

    return 0;

}

就发现
1               1
2-5            2=1*2
6-29          6=1*2*3
30-209      30=1*2*3*5
210-2309   210=1*2*3*5*7
.....
原来就是一个质数相乘
然后就用java打了表 过了!

现在在网上找了一个证明,挺好的。。供有行人学习


import java.math.BigInteger;
import java.util.Scanner;


public class Main
{
    static int pcount=0;
    static int get[]= new int[1000];
    public static  void getprime()
    {
        boolean sum[]= new boolean[1000001];
        int i,j;
        for(i=2; i<100000; i++)
        {
            if(i%2==1)sum[i]=true;
        }
        int temp=(int)Math.sqrt(100000);
        for(i=3; i<temp; i++)
        {
            if(sum[i])
            {
                for(j=i+i; j<=100000; j+=i)
                {
                    sum[j]=false;
                }
            }
        }
        sum[2]=true;
        for(i=2; i<5000; i++)
        {
            if(sum[i])get[pcount++]=i;
        }

    }
    public static void main(String args [])
    {
        int i,j;
        int  t;
        getprime();
        BigInteger val[] = new BigInteger[107];
        val[1]=new BigInteger("6");
        BigInteger b6 = new BigInteger("6");
        BigInteger b2= new BigInteger("2");
        BigInteger n ;
        for(i=2; i<105; i++)
        {
            val[i]=new BigInteger(""+get[i]).multiply(val[i-1]);
        }

        Scanner s = new Scanner(System.in);

        t=s.nextInt();
        while(t>0)
        {
            t--;
            n=s.nextBigInteger();
            if(n.compareTo(b6)<0)
            {

                if(n.compareTo(BigInteger.ONE)==0)
                {
                    System.out.println("1");
                }
                else System.out.println("2");
            }
            else
                for(i=1; i<102; i++)
                {
                    if(n.compareTo(val[i])<=0)
                    {
                        System.out.println(val[i-1]);
                        break;
                    }
                }
        }

    }
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值