算法笔记2019/11/2

一、装石头(利用二进制位数)
题目描述:把1000个石头装在10个袋子里面,任取其中的一袋,或把几个袋中的石头数加起来。都可以凑成1~1000中任何一种石头数量,求这10个袋子分别装了多少个石头?

解法:考虑1000的二进制刚好十个位,所以按照二进制转十进制的原理,1~1000中任何一个数用10位的二进制来表示时,为1的那一位就把那个袋子里面所有石头加上,为0时就不加,因此10个袋子中石头数应该是:
20  21  2  2  2  2  2  2  28  2
注意这里最后一位本来应该是2,但是由于1+2+4+8+16+32+64+128+256+512=210-1=1023>1000;
所以最后一位应该是1000-(29-1)=489;
最后得到答案:每个袋子应该装1 2 4 8 16 32 64 128 256 489

给出具体代码来检验

//装石头
#include<cstdio>
int arr[10];
int main()
{
    int j=1;
    //给每个袋子中的石头数赋值
    for(int i=0; i<10; i++)
    {
        arr[i]=1<<i;
    }
    arr[9]=489;
    //直接循环把1~1000的都检验一遍
    for(int i=1; i<=1000; i++)
    {
        int j=0,k=i;
        while(k)
        {
            if(k&1)//二进制位上是1才加入进来
                printf("%d+",arr[j]);
            k>>=1;
            j++;//移动位置
        }
        printf("=%d
",i);//是退格,为了消去多于的+号
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zdw20191029/p/14553390.html