- 注册时间
- 2007-12-27
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 3751
- 在线时间
- 小时
|
楼主 |
发表于 2009-1-7 13:21:58
|
显示全部楼层
发一下代码:- #include <cstdlib>
- #include <iostream>
- #include <windows.h>
- #include <cmath>
- #include "gmp.h"
-
- using namespace std;
-
- const int L=40;
- mpz_t Hash[10][L];
- mpz_t dif[10][10][L];
- mpz_t POW10[L];
- char str[L<<1];
-
- void Init( ){
- unsigned i, j;
- for( i=0; i<10; ++i ){
- for( j=0; j<L; ++j )
- mpz_init( Hash[i][j] );
- }
- mpz_set_ui( Hash[0][0], 0 );
- mpz_init_set_ui( POW10[0], 1 );
- for( i=1; i<10; ++i )
- mpz_set_ui( Hash[i][0], 1 );
- for( j=1; j<L; ++j ){
- mpz_init( POW10[j] );
- mpz_mul_ui( POW10[j], POW10[j-1], 10 );
- }
- for( i=0; i<10; ++i ){
- for( j=1; j<L; ++j ){
- mpz_mul_ui( Hash[i][j], Hash[i][j-1], i );
- }
- }
- for( int k=0; k<L; ++k ){
- for( i=0; i<10; ++i ){
- for( j=0; j<10; ++j ){
- mpz_init( dif[i][j][k] );
- mpz_sub( dif[i][j][k], Hash[i][k], Hash[j][k] );
- }
- }
- }
- }
-
- void Clean( ){
- unsigned i, j;
- for( i=0; i<10; ++i )
- for( j=0; j<L; ++j ){
- mpz_clear( Hash[i][j] );
- }
- for( j=0; j<L; ++j )
- mpz_clear( POW10[j] );
- for( int k=0; k<L; ++k ){
- for( i=0; i<10; ++i ){
- for( j=0; j<10; ++j ){
- mpz_clear( dif[i][j][k] );
- }
- }
- }
- }
-
- bool check( mpz_t &n, int *c ){
- int i, d[10]={0};
- mpz_get_str( str, 10, n );
- for( i=0; str[i]!='\0'; ++i ){
- d[str[i]-'0']++;
- if( d[str[i]-'0']>c[str[i]-'0'] ) return false;
- }
- return true;
- }
-
- void combination( unsigned n, unsigned m ){
- int *c=new int[m+2], j, *num=new int[m+2];
- int dig[10]={0};
- dig[0]=m;
- for( j=1; j<=m; ++j ) c[j]=j-1, num[j]=c[j]-j+1;
- c[m+1]=n;
- mpz_t number;
- mpz_init_set_ui( number, 0 );
- R2:
- if( mpz_cmp( number, POW10[m-1] )>0 && mpz_cmp( number, POW10[m] )<0 && check( number, dig ) ){
- mpz_out_str( stdout, 10, number );
- printf("\n");
- }
- if( m&1 )
- if( c[1]+1<c[2] ){
- --dig[num[1]];
- mpz_add( number, number, dif[num[1]+1][num[1]][m] );
- ++c[1], ++num[1];
- ++dig[num[1]];
- goto R2;
- }
- else{
- j=2; goto R4;
- }
- else
- if( c[1]>0 ){
- --dig[num[1]];
- mpz_sub( number, number, dif[num[1]][num[1]-1][m] );
- --c[1], --num[1];
- ++dig[num[1]];
- goto R2;
- }
- else{
- j=2; goto R5;
- };
- R4: if( c[j]>=j ){
- if( j<=m ){
- --dig[num[j]];
- mpz_sub( number, number, dif[num[j]][c[j-1]-j+1][m] );
- }
- if( j-1<=m ){
- --dig[num[j-1]];
- mpz_sub( number, number, dif[num[j-1]][0][m] );
- }
- 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;
- if( j<=m )
- ++dig[num[j]];
- if( j-1<=m )
- ++dig[num[j-1]];
- goto R2;
- }
- else
- ++j;
- R5: if( c[j]+1<c[j+1] ){
- if( j<=m ){
- --dig[num[j]];
- mpz_sub( number, number, dif[num[j]][c[j]+1-j+1][m] );
- }
- if( j-1<=m ){
- --dig[num[j-1]];
- mpz_sub( number, number, dif[num[j-1]][c[j]-j+2][m] );
- }
- 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;
-
-
- if( j<=m )
- ++dig[num[j]];
- if( j-1<=m )
- ++dig[num[j-1]];
- goto R2;
- }
- else{
- ++j;
- if( j<=m ) goto R4;
- }
- delete []c;
- delete []num;
- mpz_clear( number );
- }
-
- int main(int argc, char *argv[])
- {
- int time=GetTickCount();
- Init();
- for( unsigned i=3; i<L; ++i ){
- cout<<i<<" digits search start!\n";
- combination( i+9, i );
- }
- Clean( );
- cout<<"time : "<<GetTickCount()-time<<" ms\n";
- cout<<"press any key to continue...\n";
- cin.get();
- return EXIT_SUCCESS;
- }
复制代码 |
|