poj-1362

//356K  0MS G++
#include <cstdio>
#include <cstring>

const int MAX = 40;

long long rankWeight[MAX];

void init() {
    long long begin = 2;
    for (int i = 0; i < MAX; i++) {
        rankWeight[i] = begin - 1;
        // printf("%lld ", rankWeight[i]);
        begin <<= 1;
    }
    // printf("\n");
}
http://write.blog.csdn.net/postedit/39203945
int binarySearch(int val) {
    // printf("binarySearch %d\n", val);
    int begin = 0;
    int end = MAX-1;
    while(1) {
        if (begin > end) {
            break;
        }
        int mid = (begin + end)/2;
        if (rankWeight[mid] == val) {
            // printf("%d found!\n", val);
            return mid;
        } else if (rankWeight[mid] > val) {
            end = mid - 1;
        } else if (rankWeight[mid] < val) {
            begin = mid + 1;
        }
    }
    // printf("%d not found!\n", val);
    return -1;
}

int res[30];
int resPos;

int caseNum;

long long getMaxLessEqualThan(int demicalVal, int & weightRank) {
    long long res = 0;
    for (int i = 0; i <MAX; i++) {
        if (rankWeight[i] > demicalVal) {
            res = rankWeight[i-1];
            weightRank = i-1;
            break;
        }
    }
    return res;
}

void getSkewBinary(int demicalVal) {
    if (demicalVal == 0) {
        printf("0 []\n");
        return;
    }

    int curDemicalVal = demicalVal;

    while(1) {
        int CurValWeightRank = binarySearch(curDemicalVal);
        if (CurValWeightRank >= 0) {
            res[resPos++] = CurValWeightRank;
            break;
        } else {
            if (curDemicalVal%2==0) {
                int halfVal = curDemicalVal/2;
                if (halfVal%2 == 1) {
                    int HalfCurValWeightRank = binarySearch(halfVal);
                    if (HalfCurValWeightRank >= 0) {
                        res[resPos++] = HalfCurValWeightRank;
                        res[resPos++] = HalfCurValWeightRank;
                        break;
                    }
                }
            }

            int weightRank = -1;
            int MaxLessEqual = getMaxLessEqualThan(curDemicalVal, weightRank);
            if (MaxLessEqual == 0 || weightRank == -1) {
                break;
            } else {
                res[resPos++] = weightRank;
                curDemicalVal -= MaxLessEqual;
            }
        }
    }
    long long checkVal = 0;
    printf("%d [", demicalVal);
    for (int i = resPos-1; i >= 0; i--) {
        checkVal += rankWeight[res[i]];
        if (i >0) {
            printf("%d,", res[i]);
        } else if (i == 0) {
            printf("%d", res[i]);
        }
    }
    printf("]\n");
    // printf("%lld\n", checkVal);
}

int main() {
    init();
    scanf("%d", &caseNum);
    for (int i = 1; i <= caseNum; i++) {
        int demicalVal;
        memset(res, 0xff, sizeof(res));
        resPos = 0;
        scanf("%d", &demicalVal);
        getSkewBinary(demicalVal);
    }
}

题意比较难懂,不过懂了以后也算个小水题吧。

题意是给了一堆的进制权,i从0开始,依次是2的i+1次方减一(1, 3, 7 , 15),对于某个十进制数,都要用这些进制位将其表示出来,依照从进制权值从小到大的顺序:

另外有一点就是不能有两个相同的进制权位相邻,除非是最开始的两位。

比如:

对于 15, 【0 3 3】 也等于 15(0的权值 1 + 3的权值7 + 3的权值7 = 15),但是因为3 3不是最后两位,所以不行,

同时,因为权值都是奇数,所以不存在一个偶数有两种表示的方式 (比如 [k,k] 或者 [m])

这样策略就简单了:

对于一个十进制数S ,先看看其是否就是一个权值,如果是,那么直接将权值对应的位输出即可,

否则,再看其是是否为偶数,如果是偶数,在看S/2是否是一个权值V,如果是,那么直接输出[V,V],

否则,就找到最大的小于S的权值,将其对应位加入到结果数组中,并且,S 减去此权值,继续操作,

知道S == 0,整个过程结束.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值