话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样 的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
解题思路:共有15个位置,从逆向来看,刚好到达最后一次遇到的是花,可以得出倒数第二次遇到的也是花,即当到达第13个位置是酒共有2斗。若当前酒是奇数斗时,可知上一次遇到的一定是花,是偶数斗时,则上一次遇到的可能是花也可能是店。然后正向思维,起始酒为偶数斗,利用递归,当店数大于5,或者花数大于8或者酒数大于10时,则该种条件不成立,依次确定下个位置是花或者是店。若是花酒数减1,若是店酒数加倍。当到达第十三的位置的时候,可以确定酒数若是2斗,则满足题意,否则退到上一层,返回时注意位置的变动。
#include<iostream>
using namespace std;
char A[17] = {0};
char S[2] = {'a','b'};
int count = 0;
void libai (int a,int b,int sum ,int ix){
if(A[ix- 1] == 'a'){
a += 1;
sum = sum * 2;
}
if(A[ix - 1] == 'b'){
b += 1;
sum -= 1;
}
if(5 < a || 8 < b ||ix > 14||sum <= 0 ||sum > 10 )//剪枝,
return;
if(ix == 14 && sum == 2 ){ // 当到达第十三个位置时,sum 一定为 2,
for(int i = 1; i < 15;i++)
cout<<A[i];
count++;
cout<<endl;
return ;
}
for(int i = 0;i < 2;i++){
A[ix] = S[i];
ix += 1;
libai(a,b,sum ,ix);
ix -= 1; //返回时位置不动,故要减一。
}
}
int main(){
A[13] = A[14] = 'b';//最后两个元素一定是 b
int count_b = 0;
int count _a = 0;
int sum = 2;
int ix = 1;
libai( count_a,count_b,sum,ix);
cout<<count<<endl;
return 0 ;
}