POJ 1906 数学题

输入n, 取k使得2^k<n<=2^(k+1),  则第n个序列必有3^k这个数。

然后n = n - 2^k, 迭代,直到n=1, return。

注意2^63可以用int64存下,3^63则要打表输出,不然就高精度吧。

http://poj.org/problem?id=1906

#include <stdio.h>
#include <string.h>
#include <math.h>
int a[70];
__int64 two[70];
char three[][32]={
			"1",
			"3",
			"9",
			"27",
			"81",
			"243",
			"729",
			"2187",
			"6561",
			"19683",
			"59049",
			"177147",
			"531441",
			"1594323",
			"4782969",
			"14348907",
			"43046721",
			"129140163",
			"387420489",
			"1162261467",
			"3486784401",
			"10460353203",
			"31381059609",
			"94143178827",
			"282429536481",
			"847288609443",
			"2541865828329",
			"7625597484987",
			"22876792454961",
			"68630377364883",
			"205891132094649",
			"617673396283947",
			"1853020188851841",
			"5559060566555523",
			"16677181699666569",
			"50031545098999707",
			"150094635296999121",
			"450283905890997363",
			"1350851717672992089",
			"4052555153018976267",
			"12157665459056928801",
			"36472996377170786403",
			"109418989131512359209",
			"328256967394537077627",
			"984770902183611232881",
			"2954312706550833698643",
			"8862938119652501095929",
			"26588814358957503287787",
			"79766443076872509863361",
			"239299329230617529590083",
			"717897987691852588770249",
			"2153693963075557766310747",
			"6461081889226673298932241",
			"19383245667680019896796723",
			"58149737003040059690390169",
			"174449211009120179071170507",
			"523347633027360537213511521",
			"1570042899082081611640534563",
			"4710128697246244834921603689",
			"14130386091738734504764811067",
			"42391158275216203514294433201",
			"127173474825648610542883299603",
			"381520424476945831628649898809",
			"1144561273430837494885949696427",
			"3433683820292512484657849089281"
};
void fun(__int64 n){
    if (n<=1) return;
    int tmp;
    tmp=log(n+0.5)/log(2.0);
    if (two[tmp]==n){
        for (int i=0; i<tmp; i++) a[i]=1;
        return;
    }else{
        a[tmp]=1;
        fun(n-two[tmp]);
        return;
    }
}
int main(){
    int i,j;
    __int64 n;
    two[0]=1;
    for ( i = 1 ; i < 64 ; i++  ) {
        two[i]=two[i-1]*2;
    }
    while (scanf("%lld",&n),n){
        memset(a,0,sizeof(a));
        fun(n);
        for (i=0,j=0;i<64;i++){
            if (a[i])
                if (j==0) {
                    printf("{ %s",three[i]);
                    j=1;
                }else
                    printf(", %s",three[i]);
        }
        if (j==0) printf("{");
        printf(" }\n");

    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值