找回密码
 欢迎注册
查看: 94140|回复: 50

[擂台] 回归数

[复制链接]
发表于 2009-1-6 23:38:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
设k位数n的十进制形式为:$bar{d_{1}d_{2}...d_{k}}$。 若n满足: $bar{d_{1}d_{2}...d_{k}}=\sum_{i=1}^{k}{d_{i}^k}$ 则称n为回归数。 比如,153就是一个回归数:$153=1^{3}+5^{3}+3^{3}$。 最大的回归数有39位,40位以上(含40位)就不存在回归数了。 请写一个代码求出所有回归数,看谁的用时最少。 [所有回归数是已知的,我只是想看看是否有很好的方法来求出这些数]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-7 08:11:01 | 显示全部楼层
似乎是我提出问题的子集吧??
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-7 08:12:01 | 显示全部楼层
我猜测最小时间是1分钟内
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-7 08:15:25 | 显示全部楼层
环比不动点麻烦得多。 但在1分钟内还是蛮有挑战性的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-7 08:17:57 | 显示全部楼层
1分钟内?太夸张了吧.我倒是很希望看到这样的算法.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-7 11:05:14 | 显示全部楼层
我算17的环是10秒
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-7 11:14:16 | 显示全部楼层
我现在的算法求20位以下的回归数大概要9秒, 求出所有的回归数要1个小时.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-7 11:36:53 | 显示全部楼层
抱歉,我估计的确实有问题 10分钟都不可能算出来 程序存在问题 修改后再说
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-7 12:34:57 | 显示全部楼层
应该可以先进行下数学处理吧? 比如有那些数是不可能的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-7 13:21:58 | 显示全部楼层
发一下代码:
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <windows.h>
  4. #include <cmath>
  5. #include "gmp.h"
  6. using namespace std;
  7. const int L=40;
  8. mpz_t Hash[10][L];
  9. mpz_t dif[10][10][L];
  10. mpz_t POW10[L];
  11. char str[L<<1];
  12. void Init( ){
  13. unsigned i, j;
  14. for( i=0; i<10; ++i ){
  15. for( j=0; j<L; ++j )
  16. mpz_init( Hash[i][j] );
  17. }
  18. mpz_set_ui( Hash[0][0], 0 );
  19. mpz_init_set_ui( POW10[0], 1 );
  20. for( i=1; i<10; ++i )
  21. mpz_set_ui( Hash[i][0], 1 );
  22. for( j=1; j<L; ++j ){
  23. mpz_init( POW10[j] );
  24. mpz_mul_ui( POW10[j], POW10[j-1], 10 );
  25. }
  26. for( i=0; i<10; ++i ){
  27. for( j=1; j<L; ++j ){
  28. mpz_mul_ui( Hash[i][j], Hash[i][j-1], i );
  29. }
  30. }
  31. for( int k=0; k<L; ++k ){
  32. for( i=0; i<10; ++i ){
  33. for( j=0; j<10; ++j ){
  34. mpz_init( dif[i][j][k] );
  35. mpz_sub( dif[i][j][k], Hash[i][k], Hash[j][k] );
  36. }
  37. }
  38. }
  39. }
  40. void Clean( ){
  41. unsigned i, j;
  42. for( i=0; i<10; ++i )
  43. for( j=0; j<L; ++j ){
  44. mpz_clear( Hash[i][j] );
  45. }
  46. for( j=0; j<L; ++j )
  47. mpz_clear( POW10[j] );
  48. for( int k=0; k<L; ++k ){
  49. for( i=0; i<10; ++i ){
  50. for( j=0; j<10; ++j ){
  51. mpz_clear( dif[i][j][k] );
  52. }
  53. }
  54. }
  55. }
  56. bool check( mpz_t &n, int *c ){
  57. int i, d[10]={0};
  58. mpz_get_str( str, 10, n );
  59. for( i=0; str[i]!='\0'; ++i ){
  60. d[str[i]-'0']++;
  61. if( d[str[i]-'0']>c[str[i]-'0'] ) return false;
  62. }
  63. return true;
  64. }
  65. void combination( unsigned n, unsigned m ){
  66. int *c=new int[m+2], j, *num=new int[m+2];
  67. int dig[10]={0};
  68. dig[0]=m;
  69. for( j=1; j<=m; ++j ) c[j]=j-1, num[j]=c[j]-j+1;
  70. c[m+1]=n;
  71. mpz_t number;
  72. mpz_init_set_ui( number, 0 );
  73. R2:
  74. if( mpz_cmp( number, POW10[m-1] )>0 && mpz_cmp( number, POW10[m] )<0 && check( number, dig ) ){
  75. mpz_out_str( stdout, 10, number );
  76. printf("\n");
  77. }
  78. if( m&1 )
  79. if( c[1]+1<c[2] ){
  80. --dig[num[1]];
  81. mpz_add( number, number, dif[num[1]+1][num[1]][m] );
  82. ++c[1], ++num[1];
  83. ++dig[num[1]];
  84. goto R2;
  85. }
  86. else{
  87. j=2; goto R4;
  88. }
  89. else
  90. if( c[1]>0 ){
  91. --dig[num[1]];
  92. mpz_sub( number, number, dif[num[1]][num[1]-1][m] );
  93. --c[1], --num[1];
  94. ++dig[num[1]];
  95. goto R2;
  96. }
  97. else{
  98. j=2; goto R5;
  99. };
  100. R4: if( c[j]>=j ){
  101. if( j<=m ){
  102. --dig[num[j]];
  103. mpz_sub( number, number, dif[num[j]][c[j-1]-j+1][m] );
  104. }
  105. if( j-1<=m ){
  106. --dig[num[j-1]];
  107. mpz_sub( number, number, dif[num[j-1]][0][m] );
  108. }
  109. c[j]=c[j-1], num[j]=c[j]-j+1; c[j-1]=j-2, num[j-1]=c[j-1]-(j-1)+1;
  110. if( j<=m )
  111. ++dig[num[j]];
  112. if( j-1<=m )
  113. ++dig[num[j-1]];
  114. goto R2;
  115. }
  116. else
  117. ++j;
  118. R5: if( c[j]+1<c[j+1] ){
  119. if( j<=m ){
  120. --dig[num[j]];
  121. mpz_sub( number, number, dif[num[j]][c[j]+1-j+1][m] );
  122. }
  123. if( j-1<=m ){
  124. --dig[num[j-1]];
  125. mpz_sub( number, number, dif[num[j-1]][c[j]-j+2][m] );
  126. }
  127. c[j-1]=c[j], num[j-1]=c[j-1]-(j-1)+1; c[j]=c[j]+1, num[j]=c[j]-j+1;
  128. if( j<=m )
  129. ++dig[num[j]];
  130. if( j-1<=m )
  131. ++dig[num[j-1]];
  132. goto R2;
  133. }
  134. else{
  135. ++j;
  136. if( j<=m ) goto R4;
  137. }
  138. delete []c;
  139. delete []num;
  140. mpz_clear( number );
  141. }
  142. int main(int argc, char *argv[])
  143. {
  144. int time=GetTickCount();
  145. Init();
  146. for( unsigned i=3; i<L; ++i ){
  147. cout<<i<<" digits search start!\n";
  148. combination( i+9, i );
  149. }
  150. Clean( );
  151. cout<<"time : "<<GetTickCount()-time<<" ms\n";
  152. cout<<"press any key to continue...\n";
  153. cin.get();
  154. return EXIT_SUCCESS;
  155. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-21 21:12 , Processed in 0.027992 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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