鱼C论坛

 找回密码
 立即注册
查看: 2768|回复: 12

题目55:10000以下有多少Lychrel数?

[复制链接]
发表于 2015-6-18 22:45:11 | 显示全部楼层 |阅读模式

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

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

x

Lychrel numbers

If we take 47, reverse and add, 47 + 74 = 121, which is palindromic.

Not all numbers produce palindromes so quickly. For example,

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337

That is, 349 took three iterations to arrive at a palindrome.

Although no one has proved it yet, it is thought that some numbers, like 196, never produce a palindrome. A number that never forms a palindrome through the reverse and add process is called a Lychrel number. Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume that a number is Lychrel until proven otherwise. In addition you are given that for every number below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. In fact, 10677 is the first number to be shown to require over fifty iterations before producing a palindrome: 4668731596684224866951378664 (53 iterations, 28-digits).

Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; the first example is 4994.

How many Lychrel numbers are there below ten-thousand?

NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers.

题目:

我们将 47 与它的逆转相加,47 + 74 = 121 , 可以得到一个回文。

并不是所有数都能这么快产生回文,例如:

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337

也就是说 349 需要三次迭代才能产生一个回文。

虽然还没有被证明,人们认为一些数字永远不会产生回文,例如 196 。那些永远不能通过上面的方法(逆转然后相加)产生回文的数字叫做 Lychrel 数。因为这些数字的理论本质,同时也为了这道题,我们认为一个数如果不能被证明的不是 Lychrel 数的话,那么它就是 Lychre 数。此外,对于每个一万以下的数字,你还有以下已知条件:这个数如果不能在 50 次迭代以内得到一个回文,那么就算用尽现有的所有运算能力也永远不会得到。10677 是第一个需要 50 次以上迭代得到回文的数,它可以通过 53 次迭代得到一个 28 位的回文:4668731596684224866951378664。

令人惊奇的是,有一些回文数本身也是 Lychrel 数,第一个例子是 4994。

10000 以下一共有多少个 Lychrel 数?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-10-7 15:59:20 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-10-13 10:07 编辑
  1. 249

  2. '''10000以下有多少lychrel数'''
  3. def isCycle(num):
  4.     if num == reVerse(num):
  5.         return True
  6.     else:
  7.             return False

  8. def reVerse(num):
  9.         str1 = str(num)
  10.         str2 = str1[::-1]
  11.         return int(str2)

  12. def isLychrel(num):
  13.         cal = 1
  14.         num1 = num + reVerse(num)
  15.         if isCycle(num1):
  16.                 pass
  17.         else:
  18.                 num2 = num1
  19.                 while cal <= 50:
  20.                         num3 = num2 + reVerse(num2)
  21.                         cal += 1
  22.                         if isCycle(num3):
  23.                                 break
  24.                         else:
  25.                                 num2 = num3
  26.         if cal <= 50:
  27.                 return 0
  28.         else:
  29.                 return 1

  30. count = 0
  31. for i in range(10,10000):
  32.         if isLychrel(i):
  33.                 count += 1
  34. print(count)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-22 00:34:58 | 显示全部楼层
先算出非Lychrel数,再用9999-count
  1. def Rec(x):
  2.     tmp = list(str(x))
  3.     temp = tmp[:]
  4.     temp.reverse()
  5.     if tmp == temp:
  6.         return True
  7.     return False
  8. count = 0
  9. for i in range(1,10000):
  10.     pmt = i
  11.     for j in range(50):
  12.         tmp = ''
  13.         for n in range(1,len(str(pmt))+1):
  14.             tmp += str(pmt)[-n]
  15.         temp = pmt+int(tmp.lstrip('0'))
  16.         if Rec(temp):
  17.             count+=1
  18.             break
  19.         pmt = temp
  20.         
  21. print(9999-count)
复制代码

结果:249
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-17 14:48:53 | 显示全部楼层
  1. # encoding:utf-8
  2. # 寻找lychrel数
  3. from time import time
  4. def euler053(N=1000000):
  5.     l_result = []
  6.     for i in range(1, 10000):
  7.         num = i
  8.         flag = True
  9.         for count in range(1, 51):
  10.             num += int(str(num)[::-1])
  11.             if int(str(num)[::-1]) == num:
  12.                 flag = False
  13.                 break
  14.         if flag:
  15.             l_result.append(i)
  16.     print(len(l_result))
  17. if __name__ == '__main__':
  18.     start = time()
  19.     euler053()
  20.     print('cost %.6f sec' % (time() - start))
复制代码


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

使用道具 举报

发表于 2017-6-16 10:24:31 | 显示全部楼层
此代码使用matlab编程
Problem55所用时间为: 3.7305秒
Problem55的答案为: 249
  1. %% Problem55.m
  2. % 最后编辑时间:17-06-16 10:03
  3. % 问题:10000以下有多少个Lychrel数

  4. % Problem55所用时间为: 3.7305秒
  5. % Problem55的答案为: 249

  6. function Output = Problem55()
  7. tic

  8. Total = 0;
  9. for ii = 1:10000
  10.     if Islychrel(ii) == 1
  11.         Total = Total + 1;
  12.     end
  13. end
  14. Output = Total;
  15.                   
  16. toc
  17. disp('此代码使用matlab编程')
  18. disp(['Problem55所用时间为: ',num2str(toc),'秒'])
  19. disp(['Problem55的答案为: ',num2str(Output)])
  20. end

  21. %% Islychrel.m
  22. % 输入一个数,判定其是否为Lychrel数
  23. % 超过50次迭代,默认其不是Lychrel数
  24. function Judge = Islychrel(n)
  25. if nargin == 0
  26. n = 196;
  27. end
  28. Limit = 50 - 1;
  29. Time = 0;
  30. Now = num2str(n) - '0';

  31. Judge = 1;

  32. % Loops
  33. while (Time < Limit )
  34.     Time = Time + 1;
  35.     Next = Vector_Plus(Now,fliplr(Now));
  36.     if sum(abs(Next - fliplr(Next))) == 0;
  37.         Judge = 0;
  38.         break
  39.     else
  40.         Now = Next;
  41.     end
  42. end
  43. end

  44. %此程序实现两个向量的加法
  45. function Output=Vector_Plus(a,b)
  46. if nargin==0
  47.     a=[9 9 9 9 9 9 ];
  48.     b=[2 0];
  49. end
  50. L1=length(a);
  51. L2=length(b);
  52. L=max(L1,L2);
  53. if L1<L2
  54.    Span=L2-L1;
  55.    Newa=[zeros(1,Span),a];
  56.    Newb=b;
  57. elseif L1>L2
  58.    Span=L1-L2;
  59.    Newa=a;
  60.    Newb=[zeros(1,Span),b];
  61. else
  62.     Newa=a;
  63.     Newb=b;
  64. end
  65. Rank=Newa+Newb;
  66. for ii=L:-1:2
  67.     if Rank(ii)>=10
  68.         Rank(ii)=Rank(ii)-10;
  69.         Rank(ii-1)=Rank(ii-1)+1;
  70.     end
  71. end
  72. Biggest=0;
  73. while (Rank(1)>=10)
  74.     if Rank(1)>=10
  75.        Rank(1)=Rank(1)-10;
  76.        Biggest=Biggest+1;
  77.     end
  78. end
  79. if Biggest>0
  80.     Output=[Biggest,Rank];
  81. else
  82.     Output=Rank;
  83. end
  84. end
  85.         
  86.    
  87.         
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-30 13:24:29 | 显示全部楼层
用的matlab
结果是:
   249

时间已过 2.166115 秒。
>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-8 15:47:59 | 显示全部楼层
249


  1. def reverse_add(num):
  2.     str1 = str(num)
  3.     numList = []
  4.     for i in range(len(str1)):
  5.         numList.append(int(str1[i]))
  6.     numList.reverse()
  7.     str2 = ""
  8.     for each in numList:
  9.         str2 += str(each)
  10.     newNum = int(str2) + num
  11.     return newNum

  12. def isPalindrome(num):
  13.     if len(str(num)) % 2 == 0:
  14.         str1 = ""
  15.         str2 = ""
  16.         for i in range(len(str(num))//2):
  17.             str1 += str(num)[i]
  18.             str2 += str(num)[-1-i]
  19.         if str1 == str2:
  20.             return True
  21.         else:
  22.             return False
  23.     else:
  24.         str1 = ""
  25.         str2 = ""
  26.         for i in range(len(str(num))//2):
  27.             str1 += str(num)[i]
  28.             str2 += str(num)[-1-i]
  29.         if str1 == str2:
  30.             return True
  31.         else:
  32.             return False

  33. def isLychrel(num):
  34.     count = 1
  35.     tempNum = reverse_add(num)
  36.     while count <= 50:
  37.         if isPalindrome(tempNum):
  38.             return False
  39.         else:
  40.             tempNum = reverse_add(tempNum)
  41.             if isPalindrome(tempNum):
  42.                 return False
  43.             else:
  44.                 count += 1
  45.     if count > 50:
  46.         return True
  47.     else:
  48.         return False

  49. Lychrel_count = 0
  50. for i in range(1,10000):
  51.     if isLychrel(i):
  52.         Lychrel_count += 1

  53. print(Lychrel_count)
复制代码

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

使用道具 举报

发表于 2019-6-25 16:38:53 | 显示全部楼层
共有:249 个 Lychrel 数
用时:0.156001 秒
  1. import time

  2. def cal_result(N_range):
  3.     count = 0
  4.     for num in range(1, N_range+1):
  5.         for _ in range(50):
  6.             str_num = str(num + int(str(num)[::-1]))

  7.             if str_num == str_num[::-1]:
  8.                 count += 1
  9.                 break
  10.             else:
  11.                 num = int(str_num)
  12.     return count

  13. print("共有:{} 个 Lychrel 数\n用时:{} 秒".format(10000 - cal_result(10000), time.process_time()))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-21 16:12:59 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-4-18 12:25 编辑

Python:
  1. def isLychrel(n):
  2.     count=50
  3.     n+=int(str(n)[::-1])

  4.     while count:
  5.         reversed=int(str(n)[::-1])

  6.         if n==reversed:
  7.             return False

  8.         n+=reversed
  9.         count-=1
  10.         
  11.     return True

  12. print(sum(map(isLychrel,range(1,10000))))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-18 12:00:12 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-6-27 09:37 编辑

C++ 11ms
  1. //249 10ms
  2. #include<iostream>
  3. using namespace std;
  4. using ull=unsigned long long;


  5. ull numreverse(ull n) {
  6.     ull res = 0;

  7.     while (n) {
  8.         res = res * 10 + n % 10;
  9.         n /= 10;
  10.     }

  11.     return res;
  12. }


  13. int main() {
  14.     unsigned short res = 0;
  15.     unsigned char count;
  16.     ull i = 9999, j, reversed;

  17.     while (i) {
  18.         j = i + numreverse(i);
  19.         count = 50;

  20.         while (count--) {
  21.             reversed = numreverse(j);

  22.             if (reversed == j) {
  23.                 goto next;
  24.             }

  25.             j += reversed;
  26.         }

  27.         ++res;

  28.     next:
  29.         --i;
  30.     }

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

使用道具 举报

发表于 2020-8-19 20:19:41 | 显示全部楼层
249

Process returned 0 (0x0)   execution time : 0.167 s
Press any key to continue.
从25题搬来高精度,略作修改
  1. #include<iostream>
  2. #include<algorithm>
  3. #include<vector>
  4. using namespace std;
  5. const int M = 1e4;

  6. typedef struct BigInt{
  7.   vector<int> v;

  8.   BigInt(vector<int> v):v(v){}
  9. }BI;

  10. void operator += (BI & a,const BI & x){
  11.     vector<int> t1 = a.v;
  12.     vector<int> t2 = x.v;
  13.     if (a.v.size() < x.v.size())  swap(t1,t2);

  14.     for (int i = 0;i < max(t1.size(),t2.size() );i++){
  15.       if (i < t2.size())  t1[i] += t2[i];
  16.       if (i > 0 && t1[i-1] > 9)  {t1[i]++;  t1[i-1] -= 10;}
  17.     }

  18.     if (t1[t2.size()-1] > 9)
  19.       if (t1.size() == t2.size() )
  20.         {t1.push_back(1);  t1[t1.size()-2] -= 10;}
  21.       else  {
  22.         t1[t2.size()]++;
  23.         for (int i = t2.size();i < t1.size()-1;i++){
  24.           if (t1[i] > 9) {t1[i] -= 10;  t1[i+1]++;}
  25.           else break;
  26.         }
  27.         t1[t2.size()-1] -= 10;
  28.       }

  29.     a.v = t1;
  30. }

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

  38. bool pal(const vector<int> & v){
  39.   vector<int> u = v;
  40.   reverse(u.begin(),u.end());

  41.   for (int i = 0;i < v.size();i++)
  42.     if (u[i] != v[i]) return false;

  43.   return true;
  44. }

  45. bool lych(BI & x,BI & y){
  46.   for (int j = 1;j <= 50;j++){
  47.     x += y;
  48.     if (pal(x.v)) return false;

  49.     y.v = x.v;
  50.     reverse(y.v.begin(),y.v.end());
  51.   }
  52.   return true;
  53. }

  54. int main(){
  55.   int ans = 0;

  56.   for (int i = 1;i < M;i++){
  57.     vector<int> v,u;
  58.     trans(i,v,u);
  59.     BI x(v),y(u);
  60.     if (lych(x,y)) ans++;
  61.   }

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

使用道具 举报

发表于 2020-10-28 12:24:53 | 显示全部楼层
这个Lychrel数列表是:[196, 295, 394, 493, 592, 689, 691, 788, 790, 879, 887, 978, 986, 1495, 1497, 1585, 1587, 1675, 1677, 1765, 1767, 1855, 1857, 1945, 1947, 1997, 2494, 2496, 2584, 2586, 2674, 2676, 2764, 2766, 2854, 2856, 2944, 2946, 2996, 3493, 3495, 3583, 3585, 3673, 3675, 3763, 3765, 3853, 3855, 3943, 3945, 3995, 4079, 4169, 4259, 4349, 4439, 4492, 4494, 4529, 4582, 4584, 4619, 4672, 4674, 4709, 4762, 4764, 4799, 4852, 4854, 4889, 4942, 4944, 4979, 4994, 5078, 5168, 5258, 5348, 5438, 5491, 5493, 5528, 5581, 5583, 5618, 5671, 5673, 5708, 5761, 5763, 5798, 5851, 5853, 5888, 5941, 5943, 5978, 5993, 6077, 6167, 6257, 6347, 6437, 6490, 6492, 6527, 6580, 6582, 6617, 6670, 6672, 6707, 6760, 6762, 6797, 6850, 6852, 6887, 6940, 6942, 6977, 6992, 7059, 7076, 7149, 7166, 7239, 7256, 7329, 7346, 7419, 7436, 7491, 7509, 7526, 7581, 7599, 7616, 7671, 7689, 7706, 7761, 7779, 7796, 7851, 7869, 7886, 7941, 7959, 7976, 7991, 8058, 8075, 8079, 8089, 8148, 8165, 8169, 8179, 8238, 8255, 8259, 8269, 8328, 8345, 8349, 8359, 8418, 8435, 8439, 8449, 8490, 8508, 8525, 8529, 8539, 8580, 8598, 8615, 8619, 8629, 8670, 8688, 8705, 8709, 8719, 8760, 8778, 8795, 8799, 8809, 8850, 8868, 8885, 8889, 8899, 8940, 8958, 8975, 8979, 8989, 8990, 9057, 9074, 9078, 9088, 9147, 9164, 9168, 9178, 9237, 9254, 9258, 9268, 9327, 9344, 9348, 9358, 9417, 9434, 9438, 9448, 9507, 9524, 9528, 9538, 9597, 9614, 9618, 9628, 9687, 9704, 9708, 9718, 9777, 9794, 9798, 9808, 9867, 9884, 9888, 9898, 9957, 9974, 9978, 9988, 9999]

用时0.423738 sec,长度为:249,其中本身是回文数的有[4994, 8778, 9999]
  1. from time import time
  2. def hw(n):#回文
  3.     if str(n)==str(n)[::-1]:
  4.         return True
  5. def nz(n):#与逆转相加,不用判断前面是否有0
  6.     return n + int(str(n)[::-1])

  7. a = 1 #指针
  8. n = 1
  9. Ly = []
  10. t = time()
  11. while n <10000:
  12.     tmp = nz(n)
  13.     while a<51:
  14.         if hw(tmp):
  15.             break
  16.         else:
  17.             tmp = nz(tmp)
  18.             a += 1
  19.     if a >=51:
  20.         Ly.append(n)
  21.         a = 1
  22.     else:
  23.         a =1
  24.     n += 1
  25. l = []
  26. for i in Ly:
  27.     if hw(i):
  28.         l.append(i)   
  29. print('这个Lychrel数列表是:%s \n' % Ly)   
  30. print('用时%.6f sec,长度为:%d,其中本身是回文数的有%s' % (time()-t, len(Ly), l))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-9 10:14:23 | 显示全部楼层
应用大数库mpir。
  1. /*
  2. 欧拉问题55
  3. 答案:249
  4. 耗时:0.0325379秒(单核)
  5.      0.019746秒(4核)
  6. */
  7. #include <iostream>
  8. #include <string>
  9. #include <mpirxx.h>
  10. #include <algorithm>
  11. #include <omp.h>
  12. using namespace std;

  13. int main(void)
  14. {
  15.   double t = omp_get_wtime();
  16.   int nCount = 0;
  17. #pragma omp parallel for reduction(+:nCount)
  18.   for (int k = 1; k < 10000; ++k)
  19.   {
  20.     int nc = 0;
  21.     mpz_class a = k;
  22.     bool bFlag = true;
  23.     while (nc < 50)
  24.     {
  25.       string s1 = a.get_str();
  26.       string s2 = s1;
  27.       reverse(s2.begin(), s2.end());
  28.       if (nc > 0 && s1 == s2)
  29.       {
  30.         bFlag = false;
  31.         break;
  32.       }
  33.       ++nc;
  34.       a += mpz_class(s2, 10);
  35.     }
  36.     if (bFlag)
  37.       ++nCount;
  38.   }
  39.   t = omp_get_wtime() - t;
  40.   cout << nCount << endl << t << endl;
  41.   return 0;
  42. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 01:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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