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

[讨论] 猜猜我的手机号码?

[复制链接]
发表于 2009-8-25 11:34:42 | 显示全部楼层
如果在已知:前三位为189,末两位为43,11个数字分别为:01123456789,且为两个素数之积,其中一素数为5位数。 则存在一些快速算法,比如说: 1、根据末两位为43,且为两素数之积,可先建立100内正奇数的乘法表,筛选出积末两位为43者的组合; 2、可先建立素数表,范围为:10000~1899999; 3、试算时,在确定一素数后,可以马上确定出另一素数的取值范围; 4、在计算出两素数乘积(需64位存储)后,可以马上减去18900000043,这样仅保留中间的6位数字,可以用DWORD类型数据存储; 5、在统计数字字符时,需要将数字转化为10进制字符,此处有些快速算法,可完全避免除法指令进行提速;或将012567六个数字全排列后排序,而后进行二分查找判定。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 13:01:08 | 显示全部楼层
31# gxqcn 请提供一个代码吧 我的代码已经用到了你的若干建议
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 13:04:35 | 显示全部楼层
具体代码我不想写了,结果应该在秒级内输出。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 15:55:41 | 显示全部楼层
具体代码我不想写了,结果应该在秒级内输出。 gxqcn 发表于 2009-8-25 13:04
我用30楼代码 if( temp>189e8 && temp<190e8 )还是9秒,不知道什么时候限制1出现2次 medie2005 的最大时间耗费是什么,int64的mod /运算? 你的建议中最大缩短时间是靠什么?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 16:56:05 | 显示全部楼层
下面的代码,用了 STL,还调用了 HugeCalc 以快速生成素数表及统计耗时:
  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. #include "../../../HugeCalc_API/CppAPI/Include/HugeCalc.h" // 公共接口
  5. #pragma message( "automatic link to ../../../HugeCalc_API/CppAPI/Lib/HugeCalc.lib" )
  6. #pragma comment( lib, "../../../HugeCalc_API/CppAPI/Lib/HugeCalc.lib" )
  7. int main(int argc, char* argv[])
  8. {
  9. // printf("Hello World!\n");
  10. cout << "Call " << HugeCalc::GetVer() << endl << endl;
  11. // 初始化
  12. HugeCalc::EnableTimer( TRUE );
  13. HugeCalc::ResetTimer();
  14. UINT32 i, j;
  15. UINT32 u32Size = HugeCalc::GetPrimeCount( 10000, 1899999 );
  16. UINT32 * pPrimeBuffer = new UINT32[u32Size];
  17. HugeCalc::GetPrimeList( pPrimeBuffer, u32Size, 10000, 1899999 );
  18. UINT32 LUT[720], u32Dights[6] = { 0, 1, 2, 5, 6, 7 };
  19. UINT32 *p, *p1, *p2, *p_end;
  20. *( p = LUT ) = 1256743; /* 012567 43 */
  21. while( next_permutation( u32Dights, u32Dights+6 ))
  22. {
  23. for ( i=0, j=0; 6!=j; ++j )
  24. {
  25. i = i * 10 + u32Dights[j];
  26. }
  27. *(++p) = i * 100 + 43;
  28. }
  29. p1 = pPrimeBuffer;
  30. do
  31. {
  32. p2 = lower_bound( p1, pPrimeBuffer + u32Size, (UINT32)((UINT64)18901256743 / *p1 ));
  33. p_end = lower_bound( p2, pPrimeBuffer + u32Size, (UINT32)((UINT64)18976521043 / *p1 )+1 );
  34. do
  35. {
  36. i = (UINT32)( UInt32x32To64( *p1, *p2 ) - (UINT64)18900000000 );
  37. p = lower_bound( LUT, LUT+720, i );
  38. if ( LUT+720 != p && i == *p )
  39. {
  40. cout << ((*p>=10000000)?"189":"1890") << *p << " = " << *p1 << " * " << *p2 << endl;
  41. }
  42. }while( p_end != ++p2 );
  43. } while( *(++p1) <= 99999 );
  44. delete []pPrimeBuffer;
  45. HugeCalc::EnableTimer( FALSE );
  46. cout << endl << "耗时为:" << HugeCalc::GetTimerStr( FT_DOT06SEC_s ) << endl;
  47. return 0;
  48. }
复制代码
请将上述代码复制粘贴进 [..]\CopyrightByGuoXianqiang\HugeCalc\testDLL\src\ANSI_C++\ansi_c++.cpp,然后编译运行即可。 它运行速度非常快,结果如下:
  1. Call HugeCalc V8.1.0.0 (Win32)
  2. 18962715043 = 11173 * 1697191
  3. 18960217543 = 13037 * 1454339
  4. 18927156043 = 13187 * 1435289
  5. 18952607143 = 13291 * 1425973
  6. 18967512043 = 13799 * 1374557
  7. 18926501743 = 13841 * 1367423
  8. 18957201643 = 15077 * 1257359
  9. 18962107543 = 16223 * 1168841
  10. 18965210743 = 16631 * 1140353
  11. 18950726143 = 17123 * 1106741
  12. 18907561243 = 20357 * 928799
  13. 18965710243 = 21023 * 902141
  14. 18917062543 = 21817 * 867079
  15. 18927615043 = 21893 * 864551
  16. 18967102543 = 22247 * 852569
  17. 18920516743 = 25183 * 751321
  18. 18901652743 = 26501 * 713243
  19. 18910725643 = 28657 * 659899
  20. 18927610543 = 28807 * 657049
  21. 18912076543 = 29269 * 646147
  22. 18910765243 = 29569 * 639547
  23. 18912576043 = 33773 * 559991
  24. 18927160543 = 34351 * 550993
  25. 18961270543 = 34367 * 551729
  26. 18976105243 = 36527 * 519509
  27. 18965172043 = 37309 * 508327
  28. 18925160743 = 41981 * 450803
  29. 18910625743 = 42131 * 448853
  30. 18927016543 = 46171 * 409933
  31. 18921567043 = 46867 * 403729
  32. 18927561043 = 49463 * 382661
  33. 18951207643 = 52201 * 363043
  34. 18902756143 = 56893 * 332251
  35. 18970162543 = 66509 * 285227
  36. 18921675043 = 66571 * 284233
  37. 18917065243 = 70957 * 266599
  38. 18950126743 = 76603 * 247381
  39. 18925671043 = 83101 * 227743
  40. 18907652143 = 87049 * 217207
  41. 18916705243 = 95891 * 197273
  42. 18957062143 = 99023 * 191441
  43. 耗时为:0.174513 s
  44. Press any key to continue
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 17:17:10 | 显示全部楼层
对于gxqcn的这个问题,总共才6!=720个候选数,我觉得直接因子分解它们可能会更加快
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 18:18:34 | 显示全部楼层
分解用费马法即可.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 18:20:01 | 显示全部楼层
其实这里试除也就可以了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 18:23:26 | 显示全部楼层
用LiDIA写了个程序,不过发现速度不快6秒.这个应该是使用通用的因子分解算法的问题:
  1. #include "LiDIA/bigint.h"
  2. #include "LiDIA/rational_factorization.h"
  3. #include <algorithm>
  4. using namespace std;
  5. using namespace LiDIA;
  6. static int digitss[6]={0,1,2,5,6,7};
  7. int main()
  8. {
  9. int i,j;
  10. long long r;
  11. bigint v=1890;
  12. v*=10000000;
  13. do{
  14. for(i=0,j=0;j!=6;j++){
  15. i=i*10+digitss[j];
  16. }
  17. i=i*100+43;
  18. bigint b=v+i;
  19. rational_factorization fr(b);
  20. fr.factor(3);
  21. if(fr.no_of_comp()==2){
  22. for(j=0;j<2;j++){
  23. if(fr.exponent(j)!=1)
  24. break;
  25. }
  26. if(j==2){
  27. bigint v1=fr.base(0);
  28. bigint v2=fr.base(1);
  29. if(v1>=10000&&v1<=10000000&&v2>=10000&&v2<=10000000){
  30. int u1,u2;
  31. v1.intify(u1);v2.intify(u2);
  32. printf("189%08d=%d*%d\n",i,u1,u2);
  33. }
  34. }
  35. }
  36. }while(next_permutation(digitss,digitss+6));
  37. }
复制代码
不过结果有46个,同gxqcn不完全相同 18901652743=26501*713243 18902756143=56893*332251 18907561243=20357*928799 18907652143=87049*217207 18910625743=42131*448853 18910725643=28657*659899 18910765243=29569*639547 18912065743=111521*169583 18912076543=29269*646147 18912576043=33773*559991 18916705243=95891*197273 18917062543=21817*867079 18917065243=70957*266599 18920516743=25183*751321 18920716543=108947*173669 18921567043=46867*403729 18921675043=66571*284233 18925160743=41981*450803 18925671043=83101*227743 18926501743=13841*1367423 18927016543=46171*409933 18927156043=13187*1435289 18927160543=34351*550993 18927561043=49463*382661 18927610543=28807*657049 18927615043=21893*864551 18950126743=76603*247381 18950621743=121139*156437 18950726143=17123*1106741 18951207643=52201*363043 18952607143=13291*1425973 18957062143=99023*191441 18957201643=15077*1257359 18960217543=13037*1454339 18961027543=109507*173149 18961270543=34367*551729 18962107543=16223*1168841 18962715043=11173*1697191 18965172043=37309*508327 18965210743=16631*1140353 18965710243=21023*902141 18967102543=22247*852569 18967512043=13799*1374557 18970162543=66509*285227 18972506143=112501*168643 18976105243=36527*519509
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-8-25 18:45:58 | 显示全部楼层
我的结果与 22# medie2005 的一致。 mathe 漏了一个限定条件:其中一个素因子为5位数。 虽然候选数不多,但试乘法比因子分解法效率高得多,所以我一开始就偏向于用试算法。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-23 16:24 , Processed in 0.027768 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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