找回密码
 欢迎注册
楼主: medie2005

[讨论] Puzzle 500. 211896

[复制链接]
 楼主| 发表于 2009-8-11 13:28:35 | 显示全部楼层
本帖最后由 medie2005 于 2009-8-11 13:32 编辑

分析一下:
计算$phi(n/k)$ [1<=k<=9].
必定有:$phi(n/k)=phi(n)*1/t$. [其中,1<=t<=9, t由k以及n的素分解决定].
因此,如果n是一个解,那么,必要条件是:
$n=phi(n)*u/v$.  [其中,$u/v$是$1/1,1/2,1/3,...,1/9$中选若干个的和]
而根据u的大小,我们可以断定n的最大素因子的范围.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-8-16 16:43:18 | 显示全部楼层
继续分析一下:
由上面的分析,v<5*7*8*9.考虑等式两边2的次数,我们可以得出:
若n为偶数,则n至多含4个奇素因子;
若n为奇数,则n至多含3个奇素因子;
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-8-18 19:03:42 | 显示全部楼层
  1. #include <iostream>
  2. #include <cmath>
  3. #include <algorithm>

  4. using namespace  std;

  5. const double MAXD=15.0;
  6. const int    L=30000;
  7. __int64      prime[L];
  8. __int64      List[100];
  9. int          length;
  10. int          LLen=0;

  11. void  Init(){
  12.         prime[0]=2;
  13.         prime[1]=3;
  14.         prime[2]=7;
  15.         length=3;
  16.         for( int i=10; i<L; ++i ){
  17.                 int s=int(sqrt(i));
  18.                 bool flag=true;
  19.                 for( int j=2; j<=s && flag; ++j )
  20.                         if( i%j==0 ) flag=false;
  21.                         if( flag ){               
  22.                                 int temp=i-1;
  23.                                 for( int k=0; k<length; ++k ){
  24.                                         while( temp%prime[k]==0 ){
  25.                                                 temp/=prime[k];
  26.                                         }
  27.                                 }
  28.                                 if( temp==1 ){                       
  29.                                         prime[length++]=i;                               
  30.                                 }
  31.                         }
  32.         }
  33. }

  34. int     element[5];
  35. double  log_p[5];
  36. int     expon[5];
  37. int     count1=0;

  38. void    fun(double sum, int level, int maxlen, double MAXD){
  39.         if( level==maxlen+1 ){
  40.                 __int64 number=1, phi=1;
  41.                 for( int j=0; j<=maxlen; ++j ){
  42.                         __int64 temp=element[j];
  43.                         for( int k=0; k<expon[j]; ++k )
  44.                                 number*=temp;
  45.                         for( k=0; k<expon[j]-1; ++k )
  46.                                 phi*=temp;
  47.                         phi*=temp-1;
  48.                 }
  49.                 __int64 t=number;
  50.                 int  dig[100], index=0;
  51.                 bool flag=true;
  52.                 while( t && flag ){
  53.                         dig[index]=t%10;
  54.                         t/=10;
  55.                         if( dig[index]==0 || number%dig[index]!=0  )
  56.                                 flag=false;
  57.                         else
  58.                                 index++;
  59.                 }
  60.                 if( flag ){
  61.                         int i;               
  62.                         int  road[4]={0,0,0,0};
  63.                         int  less_than10[4]={2,3,5,7};
  64.                         for( i=0; i<sizeof(road)/sizeof(road[0]); ++i ){
  65.                                 for( int j=0; j<=maxlen; ++j ){
  66.                                         if( element[j]==less_than10[i] )
  67.                                                 road[i]=expon[j];
  68.                                 }
  69.                         }
  70.                        
  71.                         __int64 Tot=0;
  72.                         for( int k=0; k<index; ++k ){
  73.                                 switch( dig[k] ){
  74.                                 case 1 :
  75.                                         Tot+=phi;
  76.                                         break;
  77.                                 case 2 :
  78.                                         if( road[0]>1 )
  79.                                                 Tot+=phi/2;                                               
  80.                                         else
  81.                                                 Tot+=phi;
  82.                                         break;
  83.                                 case 3 :
  84.                                         if( road[1]>1 )
  85.                                                 Tot+=phi/3;
  86.                                         else
  87.                                                 Tot+=phi/2;
  88.                                         break;
  89.                                 case 4 :
  90.                                         if( road[0]>2 )
  91.                                                 Tot+=phi/4;
  92.                                         else
  93.                                                 Tot+=phi/2;
  94.                                         break;
  95.                                 case 5 :
  96.                                         if( road[2]>1 )
  97.                                                 Tot+=phi/5;
  98.                                         else
  99.                                                 Tot+=phi/4;
  100.                                         break;
  101.                                 case 6 :
  102.                                         if( road[0]>1 ){
  103.                                                 if( road[1]>1 )
  104.                                                         Tot+=phi/6;
  105.                                                 else//2^k*3^1
  106.                                                         Tot+=phi/4;
  107.                                         }
  108.                                         else{
  109.                                                 if( road[1]>1 )
  110.                                                         Tot+=phi/3;
  111.                                                 else//2^1*3^1
  112.                                                         Tot+=phi/2;
  113.                                         }                       
  114.                                         break;
  115.                                 case 7 :
  116.                                         if( road[3]>1 )
  117.                                                 Tot+=phi/7;
  118.                                         else
  119.                                                 Tot+=phi/6;
  120.                                         break;
  121.                                 case 8 :
  122.                                         if( road[0]>3 )
  123.                                                 Tot+=phi/8;
  124.                                         else
  125.                                                 Tot+=phi/4;
  126.                                         break;
  127.                                 case 9 :
  128.                                         if( road[1]>2 )
  129.                                                 Tot+=phi/9;
  130.                                         else
  131.                                                 Tot+=phi/6;
  132.                                         break;
  133.                                 }
  134.                         }       
  135.                        
  136.                         if( Tot==number ){
  137.                                 printf("%I64d\n",number);
  138.                                 List[LLen++]=number;
  139.                         }
  140.                 }
  141.                 return;
  142.         }
  143.         for( int i=1; sum+i*log_p[level]<MAXD; ++i ){
  144.                 expon[level]=i;
  145.                 fun( sum+i*log_p[level], level+1, maxlen, MAXD );
  146.                 expon[level]=0;
  147.         }
  148. }


  149. void calc(int *list, int len){
  150.         int i;       
  151.         for( i=0; i<=len; ++i )
  152.                 log_p[i]=log10(element[i]);       
  153.         fun( 0, 0, len, MAXD );
  154. }

  155. void dfs( int index, int level ){
  156.         int i;
  157.         if( level==5 ){
  158.                 calc( element, level-1 );
  159.                 return;
  160.         }
  161.         for( i=index; i<length; ++i ){
  162.                 __int64 temp=prime[i]-1;
  163.                 for( int k=0; k<level; ++k ){
  164.                         while( temp%element[k]==0 ) temp/=element[k];
  165.                 }
  166.                 if( temp==1 ){
  167.                         element[level]=prime[i];
  168.                         dfs( index+1, level+1 );
  169.                         calc( element, level );
  170.                         element[level]=0;
  171.                 }
  172.         }
  173. }

  174. void start(){
  175.         int head[]={2,3,5,7};
  176.         for( int i=0; i<sizeof(head)/sizeof(head[0]); ++i ){
  177.                 element[0]=head[i];
  178.                 dfs( i+1, 1 );
  179.         }
  180. }

  181. int  main(){
  182.         Init();
  183.         start();
  184.         cout<<"========================================\n";
  185.         sort( List, List+LLen );
  186.         __int64 *end=unique( List, List+LLen );
  187.         for( int i=0; List+i!=end; ++i )
  188.                 printf("%I64d\n",List[i]);
  189.         return 0;
  190. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-8-18 19:07:40 | 显示全部楼层
结果(1这个显然的解不在搜索范围内):
211896
61341696
141732864
219483432
1423392768
4844814336
16484622336
23362267824
28193299344
169699442688
993338339328
2344883866416
8829641374848
423732883488768
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-8-24 15:58:12 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-4-20 19:50 , Processed in 0.040670 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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