鱼C论坛

 找回密码
 立即注册
查看: 2402|回复: 7

题目70:考察φ(n)是n的一个排列的n值

[复制链接]
发表于 2015-11-5 16:13:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Totient permutation

Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of positive numbers less than or equal to 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.

The number 1 is considered to be relatively prime to every positive number, so φ(1)=1.

Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation of 79180.

Find the value of n, 1 < n < QQ20151105-2@2x.png , for which φ(n) is a permutation of n and the ratio n/φ(n) produces a minimum.

题目:

欧拉函数 φ(n)(有时也叫做phi函数)可以用来计算小于等于 n 的数字中与 n 互质的数字的个数。例如,因为 1,2,4,5,7,8 全部小于 9 并且与 9 互质,所以φ(9)=6。

数字1被认为与每个正整数互质,所以 φ(1)=1。

有趣的是,φ(87109)=79180,可以看出 87109 是 79180 的一个排列。

对于 1 < n < QQ20151105-2@2x.png ,并且 φ(n) 是 n 的一个排列的那些 n 中,使得 n/φ(n) 取到最小的 n 是多少?


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-10-16 09:50:23 | 显示全部楼层
有了第69题的算法程序,这题就是送分题了把
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-16 10:16:32 | 显示全部楼层
这题唯一的问题是上限提升了10倍,到10的7次方,所以花的时间就多了好多,好在还能算……
8319823 1.0007090511248113
Time:133.215 sec
  1. from time import clock
  2. start = clock()

  3. def getPrime(n):
  4.     primes = [True]*n
  5.     primes[0], primes[1] = False, False
  6.     for (i, prime) in enumerate(primes):
  7.         if prime:
  8.             for j in range(i*i,n,i):
  9.                 primes[j] = False
  10.     primelist = []
  11.     for (k, trueprime) in enumerate(primes):
  12.         if trueprime:
  13.             primelist.append(k)
  14.     return primelist

  15. def philist(n):
  16.     primelist = getPrime(n)
  17.     PHI = [0]*(n+1)
  18.     PHI[0], PHI[1] = -1, 1
  19.     for eachprime in primelist:
  20.         PHI[eachprime] = eachprime - 1
  21.     for i in range(len(primelist)):
  22.         p = primelist[i]
  23.         for k in range(p*p,n+1,p):
  24.                 PHI[k] = PHI[int(k/p)]*(p-1)
  25.         for j in range(p*p,n+1,p*p):
  26.             PHI[j] = PHI[int(j/p)]*p
  27.     return PHI
  28. plist = philist(10000000)

  29. minn, minnphi = 2, 2
  30. for i in range(2,10000000):
  31.     if sorted(list(str(i))) == sorted(list(str(plist[i]))):
  32.         if i/plist[i] < minnphi:
  33.             minnphi = i/plist[i]
  34.             minn = i
  35. print (minn, minnphi)

  36. end = clock()
  37. print ('Time:%.3f sec' % (end-start))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-16 13:59:13 | 显示全部楼层
303963552391
Time:4.211 sec

  1. from time import clock
  2. start = clock()

  3. def getPrime(n):
  4.     primes = [True]*n
  5.     primes[0], primes[1] = False, False
  6.     for (i, prime) in enumerate(primes):
  7.         if prime:
  8.             for j in range(i*i,n,i):
  9.                 primes[j] = False
  10.     primelist = []
  11.     for (k, trueprime) in enumerate(primes):
  12.         if trueprime:
  13.             primelist.append(k)
  14.     return primelist

  15. def philist(n):
  16.     primelist = getPrime(n)
  17.     PHI = [0]*(n+1)
  18.     for eachprime in primelist:
  19.         PHI[eachprime] = eachprime - 1
  20.     for i in range(len(primelist)):
  21.         p = primelist[i]
  22.         for k in range(p*p,n+1,p):
  23.                 PHI[k] = PHI[int(k/p)]*(p-1)
  24.         for j in range(p*p,n+1,p*p):
  25.             PHI[j] = PHI[int(j/p)]*p
  26.     return PHI
  27. plist = philist(1000000)

  28. print(sum(plist))

  29. end = clock()
  30. print ('Time:%.3f sec' % (end-start))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-24 15:48:53 | 显示全部楼层
  1. # encoding:utf-8
  2. # 寻找phi(n)为n的排列的数
  3. from time import time
  4. def getPrimes(n):
  5.     primes = [True] * n
  6.     primes[0], primes[1] = False, False
  7.     for (i, prime) in enumerate(primes):
  8.         if prime:
  9.             for j in range(i * i, n, i):
  10.                 primes[j] = False
  11.     return [k for (k, v) in enumerate(primes) if v]
  12. # 学习jerryxjr1220代码
  13. def getPhis(N):
  14.     l_primes = getPrimes(N)
  15.     l_phis = [0] * (N + 1)
  16.     for x in l_primes:
  17.         l_phis[x] = x - 1
  18.     for p in l_primes:
  19.         for x in range(p * p, N + 1, p):
  20.             l_phis[x] = l_phis[int(x / p)] * (p - 1)
  21.         for y in range(p * p, N + 1, p * p):
  22.             l_phis[y] = l_phis[int(y / p)] * p
  23.     return l_phis
  24. def euler070(N=10000000):
  25.     l_phis = getPhis(N)
  26.     minphi, num = 1.1, 0
  27.     for i in range(2, N + 1):
  28.         if sorted(list(str(i))) == sorted(list(str(l_phis[i]))):
  29.             if i / l_phis[i] < minphi:
  30.                 minphi, num = i / l_phis[i], i
  31.     print(minphi, num)   
  32. if __name__ == '__main__':
  33.     start = time()
  34.     euler070()
  35.     print('cost %.6f sec' % (time() - start))
复制代码

1.0007090511248113 8319823
cost 58.685000 sec
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-19 11:08:30 | 显示全部楼层
  1. P = []
  2. L = list(range(10000000))
  3. for i in range(2, len(L)):
  4.   if L[i] == i:
  5.     P.append(i)
  6.     L[i] = i - 1
  7.   for p in P:
  8.     if i * p >= len(L):
  9.       break
  10.     if i % p == 0:
  11.       L[i*p] = L[i] * p
  12.       break
  13.     L[i*p] = L[i] * (p - 1)

  14. print(min(map(lambda x: [x[0] / x[1], x[0]], filter(lambda x: sorted(str(x[0])) == sorted(str(x[1])), list(enumerate(L))[2:])))[1])
复制代码

https://github.com/devinizz/project_euler/blob/master/page02/70.py
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-3 20:10:50 | 显示全部楼层
8319823

Process returned 0 (0x0)   execution time : 32.889 s
Press any key to continue.
思路相同的c++实现
  1. #include<algorithm>
  2. #include<iostream>
  3. #include<vector>
  4. #include<cmath>
  5. using namespace std;

  6. const int M = 1e7;

  7. int ct = 0;
  8. bool prime[M+10];
  9. int factor[M+10];
  10. int phi[M+10] = {0};

  11. void euler_sieve(){
  12.   prime[1] = false;
  13.   for (int i = 2;i <= M;i++) prime[i] = true;

  14.   for (int i = 2;i <= M;i++){
  15.     if (prime[i]) {factor[++ct] = i;  phi[i] = i-1;}
  16.     for (int j = 1;j <= ct && i*factor[j] < M;j++){
  17.       prime[i*factor[j]] = false;
  18.       if (i % factor[j] == 0) break;
  19.     }
  20.   }
  21. }

  22. void ini(){
  23.   for (int i = 2;i <= sqrt(M);i++){
  24.     if (prime[i]){
  25.       for (int j = i;j*i <= M;j++)
  26.         if (j % i == 0) phi[j*i] = phi[j] * i;
  27.         else            phi[j*i] = phi[j] * (i-1);
  28.     }
  29.   }
  30. }

  31. void parse(vector<int> & v,int x){
  32.   while(x){
  33.     v.push_back(x % 10);
  34.     x /= 10;
  35.   }
  36. }

  37. int main(){
  38.   euler_sieve();  ini();
  39.   int ans;
  40.   double minn = M;

  41.   for (int n = 2;n < M;n++){
  42.     vector<int> a,b;
  43.     double t = n / (double)phi[n];  //cout << t << endl;

  44.     parse(a,n);   parse(b,phi[n]);
  45.     sort(a.begin(),a.end());
  46.     sort(b.begin(),b.end());

  47.     if (a == b){
  48.       if (t < minn)  {minn = t; ans = n;}
  49.     }
  50.   }
  51.   cout << ans << endl;
  52.   return 0;
  53. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-31 12:47:43 From FishC Mobile | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2021-2-20 20:37 编辑

C++ 133ms
  1. #include<iostream>
  2. #include<vector>
  3. #include<limits>
  4. #include<cstring>
  5. using namespace std;



  6. template<size_t size, typename T>
  7. void euler_sieve(bool(&is_prime)[size], vector<T>& primes, T(&phi)[size]) {
  8.     T i, k;
  9.     memset(is_prime, -1, size);
  10.     is_prime[0] = is_prime[1] = 0;

  11.     for (i = 2; i < size; i++) {
  12.         if (is_prime[i]) {
  13.             primes.push_back(i);
  14.             phi[i] = i - 1;
  15.         }

  16.         for (T j : primes) {
  17.             k = i * j;

  18.             if (k >= size) {
  19.                 break;
  20.             }

  21.             is_prime[k] = false;

  22.             if (!(i % j)) {
  23.                 phi[k] = phi[i] * j;
  24.                 break;
  25.             }

  26.             phi[k] = phi[i] * (j - 1);
  27.         }
  28.     }
  29. }



  30. bool is_permutation(unsigned int a, unsigned int b)noexcept {
  31.     unsigned int t;
  32.     unsigned char digits[10] = { 0 };

  33.     while (a) {
  34.         t = a;
  35.         a /= 10;
  36.         digits[t - a * 10]++;
  37.     }

  38.     while (b) {
  39.         t = b;
  40.         b /= 10;
  41.         digits[t - b * 10]--;
  42.     }

  43.     return !((*(unsigned long long*)(&digits)) | (*(unsigned short*)(&digits[8])));
  44. }



  45. int main() {
  46.     ios::sync_with_stdio(false);

  47.     constexpr unsigned int UPPER_BOUND = 10000000;
  48.     static bool is_prime[UPPER_BOUND];
  49.     static unsigned int phi[UPPER_BOUND];
  50.     vector<unsigned int> primes;
  51.     double min_div = numeric_limits<double>::max(), div;
  52.     unsigned int min_n = 0, n;

  53.     euler_sieve(is_prime, primes, phi);


  54.     for (n = 2; n < UPPER_BOUND; n++) {
  55.         div = (double)n / phi[n];

  56.         if (div < min_div && is_permutation(n, phi[n])) {
  57.             min_div = div;
  58.             min_n = n;
  59.         }
  60.     }


  61.     cout << min_n << endl;
  62.     return 0;
  63. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-2 13:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表