- 注册时间
- 2007-12-26
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 92615
- 在线时间
- 小时
|
楼主 |
发表于 2009-8-16 07:46:30
|
显示全部楼层
优化版本
- // http://bbs.emath.ac.cn/viewthread.php?tid=1689&page=2&fromuid=8#pid21088
-
- #include <iostream>
- #include <ctime>
-
- #include <vector>
- #include <map>
- using namespace std;
-
-
- typedef unsigned int UINT32, *PUINT32;
- typedef unsigned __int64 UINT64, *PUINT64;
-
- typedef struct node
- {
- UINT32 key;
- UINT32 value;
- }NODE;
-
- typedef vector< NODE > NODE_VECTOR;
- typedef map< UINT32, UINT32 > KEY_INDEX_MAP;
- typedef KEY_INDEX_MAP::value_type MVT;
-
- #ifndef UInt32x32To64
- # define UInt32x32To64(a, b) ((UINT64)(((UINT64)(a)) * ((UINT64)(b))))
- #endif
-
- char szResult[128];
-
- // http://bbs.emath.ac.cn/viewthread.php?tid=1207&page=6&fromuid=8#pid16108
- UINT32 Sqrt( UINT32 n )
- {
- UINT32 t;
- UINT32 ret = 0;
-
- #define SQRT_CORE(x) \
- t = ret + (1UL<<(x)); \
- ret >>= 1; \
- if ( n >= t ) \
- { \
- n -= t; \
- ret += (1UL<<(x)); \
- }
-
- SQRT_CORE(30);
- SQRT_CORE(28);
- SQRT_CORE(26);
- SQRT_CORE(24);
- SQRT_CORE(22);
- SQRT_CORE(20);
- SQRT_CORE(18);
- SQRT_CORE(16);
- SQRT_CORE(14);
- SQRT_CORE(12);
- SQRT_CORE(10);
- SQRT_CORE(8);
- SQRT_CORE(6);
- SQRT_CORE(4);
- SQRT_CORE(2);
- SQRT_CORE(0);
-
- #undef SQRT_CORE
-
- return ret;
- }
-
- const char * GetMin01( UINT32 n )
- {
- char * p = szResult;
-
- UINT32 i=0, j=0, d, ten, bits, index, size0, size1;
- UINT32 key, SqrtN;
- UINT32 value;
-
- NODE info;
- NODE_VECTOR vNode;
- KEY_INDEX_MAP mKeyIndex;
-
- KEY_INDEX_MAP::iterator it;
-
- *( p += 127 ) = '\0';
-
- // if ( 0 == n ) return p;
-
- while ( 0 == ( 1 & n ))
- {
- ++i; //times of prime 2
- n >>= 1;
- }
- while ( 0 == n % 5 )
- {
- ++j; //times of prime 5
- n /= 5;
- }
- if ( i < j ) i = j; //max times of prime 2 and prime 5
- memset( p -= i, '0', i * sizeof(char));
-
- if ( 1 == n )
- {
- *(--p) = '1';
-
- return p;
- }
-
- //special case that n+1 is 10^j
- i = n + 1;
- j = 0;
- while ( 0 == i % 10 )
- {
- ++j;
- i /= 10;
- }
- if ( 1 == i )
- {
- j *= 9;
- memset( p -= j, '1', j * sizeof(char));
-
- return p;
- }
-
- switch( n )
- {
- case 3:
- case 37: n = 111;
- break;
-
- case 7:
- case 13: n = 1001;
- break;
-
- case 337: n = 1011;
- break;
-
- case 367: n = 1101;
- break;
-
- default:
- break;
- }
-
- i = n;
- j = 0;
- while (( d = i % 10 ) <= 1 )
- {
- *(--p) = '0' + d;
- if ( 0 == ( i /= 10 ))
- {
- return p;
- }
-
- ++j;
- }
- p += j;
-
- const UINT32 INIT4BITS[] = { 0, 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, };
- for ( i=0; 16!=i; ++i )
- {
- info.key = INIT4BITS[i] % n;
- info.value = i;
- vNode.push_back( info );
- mKeyIndex.insert( MVT( info.key, i ));
- }
- index = i - 1;
-
- SqrtN = Sqrt( n );
- for ( bits=4, ten=10000%n, size1=size0=vNode.size(); ; )
- {
- for ( i=1; size0!=i; ++i )
- {
- d = (UINT32)( UInt32x32To64( vNode[i].key, ten ) % n );
- if ( mKeyIndex.end() != ( it = mKeyIndex.find( n - d )))
- {
- value = vNode[(*it).second].value;
- do
- {
- *(--p) = '0' + ( 1 & value );
- value >>= 1;
- } while( 0 != --bits );
-
- value = vNode[i].value;
- do
- {
- *(--p) = '0' + ( 1 & value );
- } while( 0 != ( value >>= 1 ));
-
- return p;
- }
- }
-
- for ( i=1; size1!=i; ++i )
- {
- d = (UINT32)( UInt32x32To64( vNode[i].key, ten ) % n );
- value = vNode[i].value << bits;
-
- for ( j=0; size0!=j; ++j )
- {
- key = vNode[j].key + d;
- if ( key < d || key >= n )
- {
- key -= n;
- }
- if ( mKeyIndex.end() == mKeyIndex.find( key ))
- {
- mKeyIndex.insert( MVT( info.key = key, ++index ));
- info.value = vNode[j].value | value;
- vNode.push_back( info );
- }
- }
- }
-
- if ( size1 == size0 )
- {
- bits <<= 1;
- ten = (UINT32)( UInt32x32To64( ten, ten ) % n );
- }
- else
- {
- ++bits;
- ten = (UINT32)( UInt32x32To64( ten, 10 ) % n );
- }
-
- size0 = vNode.size();
- if ( size0 <= SqrtN /*&& bits < 16*/ )
- {
- size1 = size0;
- }
- else
- {
- size1 = 2;
- }
- }
-
- return p;
- }
-
-
- int main( void )
- {
- UINT32 n;
- const char * p;
-
- while( 1 )
- {
- cout << "N=";
- cin >> n;
-
- if( 0 == n )
- {
- break;
- }
-
- clock_t start=clock();
- p = GetMin01( n );
- clock_t end=clock();
-
- cout << p << "\n";
- cout<< "Total cost " << end-start << "ms" << "\n" << endl;
- }
-
- return 0;
- }
复制代码 Change list:
1、新增整数开方函数;
2、将 value 由 UINT64 修改成 UINT32 |
|