一、装石头(利用二进制位数)
题目描述:把1000个石头装在10个袋子里面,任取其中的一袋,或把几个袋中的石头数加起来。都可以凑成1~1000中任何一种石头数量,求这10个袋子分别装了多少个石头?
解法:考虑1000的二进制刚好十个位,所以按照二进制转十进制的原理,1~1000中任何一个数用10位的二进制来表示时,为1的那一位就把那个袋子里面所有石头加上,为0时就不加,因此10个袋子中石头数应该是:
20 21 22 23 24 25 26 27 28 29
注意这里最后一位本来应该是29,但是由于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 <iostream> #include<cmath> using namespace std; int n,number; int a[20]= {0}; int Try(int x,int y)/*测试x行y列可否摆放棋子*/ { int j=1; while(j<x) /*与数组中已放好的数比较*/ { if((a[j]==y)||(abs(x-j)==abs(a[j]-y))) return 0; j++; } return 1; } void place(int x)//递归,x代表放置第几个棋子 { if(x>n) number++;//print();/*已到末尾结束,打印结果*/ else { for(int y=1; y<=n; y++) /*控制每一列的棋子进行尝试*/ { if(Try(x,y))//如果可以摆放 { a[x]=y;//在a中标记一下 place(x+1);/*继续下一列的递归*/ } } } } int main() { cin>>n; place(1); cout<<number<<endl; }
该文章为了记录大黑狗抄袭的每一次
标签:10,二进制位,笔记,石头,int,算法,袋子,1000 From: https://www.cnblogs.com/nmsx/p/18687912