题目链接

和上面几题差不多的

Euler's Totient function, φ(n) [sometimes called the phi function]:小于等于n的数并且和n是互质的数的个数

存在这样的数:N的欧拉数φ(n),是N的一个排列

例如:φ(87109)=79180

求在1---10^7中n/φ(n) 取到最小的 n 是多少?

这里的是p是n的素因子,当素因子有相同的时候只取一个

任意一个正整数都能分解成若干个素数乘积的形式

直接利用上题的phi函数就可以求解

这个是跑的最快的函数了

long phi2(long n){
long res = 0;
if(n==1) return 0;
int pi=2;
res = n;
while(pi*pi <=n){
if(n%pi==0){
res/=pi;
res*=(pi-1);
while(n%pi==0){
n/=pi;
}
}
pi++;
}
if(n>1){
res/=n;
res*=(n-1);
}
return res;
}
// 8319823
// running time=89s43ms

运行结果也90s了

然后考虑到

这里的pi都是素数

所以我们可以只考虑素数的情况

当n%pi==0的时候这个pi就符合条件,并去重

void run2(){
long Max_n = 10000000;
int Prime_len=400;
int[] Prime = new int[Prime_len];
Prime[0] = 2;
int k=1;
int p=1;
while(k<Prime_len){
if(isPrime(p)){
Prime[k++] = p;
}
p+=2;
} long result = 0;
double minvalue=10000;
long euler = 0 ;
for(long n = 2;n<Max_n;n++){
euler = phi3(n,Prime);
if(isPerm(euler,n)){
double temp = n/(euler*1.0);
if(temp<minvalue){
minvalue = temp;
result = n;
}
}
}
System.out.println(result); }

结果:

//    8319823
// running time=58s426ms

时间少了30s

这里缺点是要取多少个素数?

我从100,200,300,400,在400的时候结果是正确的

全部程序:

package project61;

public class P70{
void run2(){
long Max_n = 10000000;
int Prime_len=400;
int[] Prime = new int[Prime_len];
Prime[0] = 2;
int k=1;
int p=1;
while(k<Prime_len){
if(isPrime(p)){
Prime[k++] = p;
}
p+=2;
} long result = 0;
double minvalue=10000;
long euler = 0 ;
for(long n = 2;n<Max_n;n++){
euler = phi3(n,Prime);
if(isPerm(euler,n)){
double temp = n/(euler*1.0);
if(temp<minvalue){
minvalue = temp;
result = n;
}
}
}
System.out.println(result); }
// 8319823
// running time=58s426ms long phi3(long n,int[] Prime){
long res = 0;
if(n==1) return 0;
int len = Prime.length;
res = n;
int i=0; //&& n>=Prime[i]
while(i <len && n>=Prime[i] ){
if(n%Prime[i]==0){
res/=Prime[i];
res*=(Prime[i]-1);
while(n%Prime[i]==0){
n/=Prime[i];
}
}
i++;
}
if(n>1){
res/=n;
res*=(n-1);
}
return res;
}
void run(){
long Max_n = 10000000;
long result = 0;
double minvalue=10000;
long euler = 0 ;
for(long n = 2;n<Max_n;n++){
euler = phi2(n);
if(isPerm(euler,n)){
double temp = n/(euler*1.0);
if(temp<minvalue){
minvalue = temp;
result = n;
}
}
}
System.out.println(result);
}
boolean isPerm(long a,long b){
int[] label = new int[10];
while(a!=0&&b!=0){
label[(int) (a%10)]+=1;
label[(int) (b%10)]-=1;
a/=10;
b/=10; }
if(a!=0) return false;
if(b!=0) return false;
for(int i=0;i<10;i++)
if(label[i]!=0)
return false;
return true;
} boolean isPrime(int n){
if(n==2||n==3||n==5||n==7||n==11) return true;
if(n<2||n%2==0||n%3==0) return false;
for(int i=5;i<=Math.sqrt(n)+1;i++){
if(n%i==0) return false;
}
return true;
} long phi2(long n){
long res = 0;
if(n==1) return 0;
int pi=2;
res = n;
while(pi*pi <=n){
if(n%pi==0){
res/=pi;
res*=(pi-1);
while(n%pi==0){
n/=pi;
}
}
pi++;
}
if(n>1){
res/=n;
res*=(n-1);
}
return res;
}
// 8319823
// running time=89s43ms
// public static void main(String[] args){ long start = System.currentTimeMillis();
new P70().run2();
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("running time="+time/1000+"s"+time%1000+"ms"); }
}

一直感觉这个程序还可以优化

是否还有好的算法

在解题论坛上,有个解答程序看不懂,然后我就敲成java,用时8s。。。快了好多的

long[] cal_phi(){
long[] phi=new long[Max_n+1];
for(int i=1;i<Max_n;i++){
phi[i]+=i;
for(int j=2*i;j<Max_n;j+=i)
phi[j]-=phi[i];
}
return phi;
}

8s

这个是产生Max_n的所以的欧拉函数,这个虽然是两层循环,但是效率很高的,变量完就得到欧拉函数值

下面一种形式:

long[] cal_phi2(){
long[] phi = new long[Max_n+1];
for(int i=1;i<Max_n;i++)
phi[i] = i;
for(int i=2;i<Max_n;i++){
if(phi[i]==i)
phi[i] = i - 1;
for(int j=2*i;j<Max_n;j+=i)
phi[j]*=(1-1.0/i);
}
return phi;
}

15s

//    8319823
// running time=14s577ms

至于上面是何总介绍?我还不明白

在解题报告中,还有一种是利用到素数,奇数,偶数还不明白为什么的。

全部程序:

package project61;

public class P70_1{
int Max_n = 10000000;
void run(){
long[] phi=cal_phi();
int result = 0;
double minvalue = 10000.0;
for(int n=2;n<Max_n;n++){
long euler = phi[n];
if(isPerm(euler,n)){
double temp = n/(euler*1.0);
if(temp<minvalue){
minvalue = temp;
result = n;
}
} }
System.out.println(result); } long[] cal_phi(){
long[] phi=new long[Max_n+1];
for(int i=1;i<Max_n;i++){
phi[i]+=i;
for(int j=2*i;j<Max_n;j+=i)
phi[j]-=phi[i];
}
return phi;
}
// 8319823
// running time=7s855ms
long[] cal_phi2(){
long[] phi = new long[Max_n+1];
for(int i=1;i<Max_n;i++)
phi[i] = i;
for(int i=2;i<Max_n;i++){
if(phi[i]==i)
phi[i] = i - 1;
for(int j=2*i;j<Max_n;j+=i)
phi[j]*=(1-1.0/i);
}
return phi;
}
// 8319823
// running time=14s577ms
boolean isPerm(long a,long b){
int[] label = new int[10];
while(a!=0&&b!=0){
label[(int) (a%10)]+=1;
label[(int) (b%10)]-=1;
a/=10;
b/=10; }
if(a!=0) return false;
if(b!=0) return false;
for(int i=0;i<10;i++)
if(label[i]!=0)
return false;
return true;
} boolean isPrime(long n){
if(n==2||n==3||n==5||n==7) return true;
if(n<2||n%2==0||n%3==0) return false;
for(int i=5;i<=Math.sqrt(n);i++)
if(n%i==0) return false;
return true;
}
public static void main(String[] args){
long start = System.currentTimeMillis();
new P70_1().run();
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("running time="+time/1000+"s"+time%1000+"ms");
}
}

上面的程序用Python实习时间好长的

欧拉工程第70题:Totient permutation的更多相关文章

  1. 欧拉工程第69题:Totient maximum

    题目链接 欧拉函数φ(n)(有时也叫做phi函数)可以用来计算小于n 的数字中与n互质的数字的个数. 当n小于1,000,000时候,n/φ(n)最大值时候的n. 欧拉函数维基百科链接 这里的是p是n ...

  2. 欧拉工程第52题:Permuted multiples

    题目链接 题目: 125874和它的二倍,251748, 包含着同样的数字,只是顺序不同. 找出最小的正整数x,使得 2x, 3x, 4x, 5x, 和6x都包含同样的数字. 这个题目相对比较简单 暴 ...

  3. 欧拉工程第68题:Magic 5-gon ring

    题目链接 任意一条线上的三个数的和都等于9,顺时针,从最小的外圈开始,得到的序列是:432621213 和             序列 9位的字符串:三角环所能形成的最大字符串为432621513. ...

  4. 欧拉工程第67题:Maximum path sum II

    By starting at the top of the triangle below and moving to adjacent numbers on the row below, the ma ...

  5. 欧拉工程第66题:Diophantine equation

    题目链接 脑补知识:佩尔方差 上面说的貌似很明白,最小的i,对应最小的解 然而我理解成,一个循环的解了,然后就是搞不对,后来,仔细看+手工推导发现了问题.i从0开始变量,知道第一个满足等式的解就是最小 ...

  6. 欧拉工程第65题:Convergents of e

    题目链接 现在做这个题目真是千万只草泥马在心中路过 这个与上面一题差不多 这个题目是求e的第100个分数表达式中分子的各位数之和 What is most surprising is that the ...

  7. 欧拉工程第56题:Powerful digit sum

    题目链接   Java程序 package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; im ...

  8. 欧拉工程第55题:Lychrel numbers

    package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; import java.util ...

  9. 欧拉工程第54题:Poker hands

    package projecteuler51to60; import java.awt.peer.SystemTrayPeer; import java.io.BufferedReader; impo ...

随机推荐

  1. 【Qt】QDialog之屏蔽Esc键【转】

    简述 Qt中Esc键会在一些控件中默认的进行一些事件的触发,比如:QDialog,按下Esc键窗口消失.大多数情况下,我们不需要这么做,那么就需要对默认事件进行屏蔽. 简述 源码分析 事件过滤器 事件 ...

  2. Noesis.Javascript.dll 引用时报错“找不到指定的模块”

    Could not load file or assembly 'Noesis.Javascript.dll' or one of its dependencies. 找不到指定的模块. 通过反编译发 ...

  3. JDK 动态代理实现原理

    一.引言 Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象便能动态生成代理类.代理类会负责将所有方法的调用分派到委托对象上反射执行,在分派执行的过 ...

  4. jQuery之$(document).ready()使用介绍

    学习jQuery的第一件事是:如果你想要一个事件运行在你的页面上,你必须在$(document).ready()里调用这个事件 学习jQuery的第一件事是:如果你想要一个事件运行在你的页面上,你必须 ...

  5. CSS各个浏览器Hack的写法

    Hack是针对不同的浏览器去写不同的CSS样式,从而让各浏览器能达到一致的渲染效果,那么针对不同的浏览器写不同的CSS CODE的过程,就叫CSS HACK,同时也叫写CSS Hack.然后将Hack ...

  6. StackExchange.Redis的使用

    StackExchange.Redis介绍 有需要了解的和基础的使用可以参考:http://www.cnblogs.com/bnbqian/p/4962855.html StackExchange.R ...

  7. 2016 系统设计第一期 (档案一)MVC 控制器接收表单数据

    1.FormCollection collection   user.UserId =Convert.ToInt32(collection["UserId"]); /// < ...

  8. Spring中后台字符串国际化

    1.在工程的资源文件夹(source folder)中建立三个properties文件:messages.properties(默认).messages_zh_CN.properties(中文).me ...

  9. ubuntu12.04之后该死的文件关联

    这是抱怨贴~~~当然也提供了解决方法~敬请期待. 这个帖子中我们介绍如何在ubuntu下安装quartus II 13.1,安装完毕功能正常,但是有个“小问题”就是如何在文件管理器中(这里是nauti ...

  10. Web UI Design Patterns 2014

    http://www.uxpin.com/web-design-patterns.html?utm_source=Interaction%20Design%20Best%20Practices%20V ...