将2^n (n<=1000000) 转化为10进制输出

 

#include <cstdio>
#include 
<iostream>
using namespace std;
#define MAXN 360000
#define OneNode 1000000000//div每次取9位10进制数
const __int64 base = ((__int64)1)<<32;

unsigned 
long bin[MAXN];
long len;

long ret[MAXN/8];
long cnt;

void init(char *str)//2进制数转换为2^32进制数
{
    
long i;
    
for(i=0;i<n/32;i++)
    {bin[i] 
= 0;}
    bin[i] 
= 1<<(n%32);
    len 
= n/32+1;
}

void cal_length()
{
    
long i;
    
for(i=len-1;i>=0;i--)
    {
if(bin[i]) break;}
    len 
= i+1;
    
if(len==0)
        len 
= 1;
}

long div()//2^32进制转化为10^9进制,每次取得9位低位10进制数(类比10进制转化为2进制的取模求低位数),过程中需要将2^32进制数转化为10进制数以执行取模运算
{
    
long i;
    
long carry = 0;
    __int64 tmp;
    
for(i=len-1;i>=0;i--)//len是该2^32进制数的位数
    {
        tmp 
= carry*base + bin[i];
        carry
= tmp % OneNode;
        bin[i] 
= tmp/OneNode;
    }
    cal_length();
//该32进制数的位数减少了(类比10进制数转化为2进制数的过程中原数的位数在不断减少)
    return carry;
}


bool iszero()
{
    
if(len==1&&bin[0]==0return true;
    
else
        
return false;
}

void solve()
{
    
long i;
    cnt 
= 0;
    
while(!iszero())//当该数为0时,转换完成
    {
        ret[cnt
++= div();
    }
    printf(
"%ld",ret[cnt-1]);
    
for(i=cnt-2;i>=0;i--)
        printf(
"%09ld",ret[i]);//每次输出9位,不足9位的在高位处用0补上
    printf("\n");
}

int main()
{
    
long n;
    
while(scanf("%ld",&n)!=EOF)
    {
        init(n);
        solve();
    }
    
return 0;
}

 

 

高进制转化为低进制,除进制取余,除尽取反。
低进制转化为高进制,各位乘幂权求和。

复杂度为

O(以10^9为底的2^n的对数 * 以2^32为底的2^n的对数)=O(lg2/288*n^2)

        调用div()的次数,即是        div()内for循环的执行
        2^n化为10^9进制数的位    次数,即是2^n化为2^32
        数                                  进制数的位数

 

PS:考试结束!!!蓝蓝路!!!!!!!!!!!

posted @ 2009-01-15 20:55  Beetlebum  阅读(420)  评论(0编辑  收藏  举报