从零起步看算法(第14天 4.23)
一条咸鱼,该了几天之后又回来了。
写给自己:1.想得多,不如脚踏实地的干点事情。
2.还是要让自己的节奏快起来,紧起来,管好自己,不进则退。
最后,加油吧,少年!
//q15二进制枚举子集
1.用二进制枚举子集,1表示取,0表示不取
2.位运算,与,或,异或
3.左移,右移
例题:
李白喝酒,遇店加一倍,遇花喝一斗。已知最后遇见一朵花,正好喝完所有的酒。
用二进制枚举法,代码如下:
int ans = 0;
for (int i = 0; i < (1<<14); ++i) {
int tot_1 = 0;
int tot_0 = 0;
int num = 2;
for (int j = 0; j < 14; ++j) {
if (i&(1 << j)) { // 这里判断二进制 i 从右数第 j + 1 位是否为 1
tot_1++;
num = num * 2;
} else {
tot_0++;
num = num - 1;
}
}
if (tot_1 == 5 && tot_0 == 9 && num == 1) {
++ans; // 记录合法方案数
}
}
自己理解写的:
巧妙在于子集的方案选取
//q15 用二进制枚举法,算李白喝酒
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
int ans=0;
for(int i=0;i<(1<<14);++i){//二进制转换
int tos_0=0;//遇花喝一斗
int tos_1=0;//遇店加一倍
int num=2;//壶中两斗酒
for(int j=0;j<14;j++){//进位数
if(i&(1<<j)){// 这里判断二进制 i 从右数第 j + 1 位是否为 1
tos_1++;
num=num*2;
}
else{
tos_0++;
num=num-1;
}
}
if(tos_1==5&&tos_0==9&&num==1){//最后遇见花
++ans;//记录方案
}
}
cout<<ans<<endl;
return 0;
}