当前位置:   article > 正文

2014 年蓝桥杯 C 语言 B 组省赛第 3 题: 李白打酒_李白打酒c语言

李白打酒c语言

题目

标题:李白打酒

话说大诗人李白,一生好饮。幸好他从不开车。

一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。

注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。

题目分析

关于方案数量的问题往往都是使用深搜. 使用递归实现深搜可以使我们不必关心遍历的具体过程, 只需要把题目中给出的条件转换成程序语言即可.
根据题目信息, 变量有"店", “酒"和"花”, 因此我们的递归函数必须包含这三个变量, 即:

void f(int dian, int hua, int jiu)...
  • 1

根据"逢店加一倍,遇花喝一斗。"可以得出如下两个对函数 f() 自身进行调用的语句:

if(遇到店){
  f(dian-1,hua,jiu*2);
}

if(遇到花){
  f(dian,hua-1,jiu-1);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

递归的边界是遇到了 5 次店, 10 次花, 并且最后酒喝光了, 即:

dian==0&&hua==0&&jiu==0
  • 1

但是上面的分析过程 (对递归边界的定义) 是存在错误的. 我们根据上面的分析过程可以写出下面这个 (错误的) 程序:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int ans=0;

void f(int dian, int hua, int jiu){
		if(dian>0&&jiu>=0){
			f(dian-1,hua,jiu*2);
		}

		if(hua>0&&jiu>=1){
			f(dian,hua-1,jiu-1);
		}

		if(dian==0&&hua==0&&jiu==0){
			ans++;
		}

	}

int main(){

	f(5,10,2);
	cout<<ans<<endl;

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

上面这个程序的运行结果是:
27

"27"看上去也"像是"一个正确答案. 但是, 如果我们仔细分析题目就会发现, 上面这个程序没有满足题目中给出的下面这个条件:

已知最后一次遇到的是花,他正好把酒喝光了
  • 1

也就是说, 李白最后一次遇到的是花, 而且在刚遇到的花的时候, 他的酒壶里还剩 1 斗酒, 随后"遇花喝一斗"把酒壶里面的酒都喝光了. 至此, 李白一共遇到了 5 次店, 10 次花, 并且喝完了全部的酒.

但是, 在上面的程序中, 计算的仅仅是李白"遇到了 5 次店, 10 次花, 并且喝完了全部的酒", 存在李白最后连续遇到了两次花, 每次喝一斗, 最后把酒喝完的情况, 也存在李白最后连续遇到了四次花, 每次喝一斗, 最后把酒喝完的情况(题目中没有提到酒壶容量的上限).

为了满足这个"已知最后一次遇到的是花,他正好把酒喝光了"的条件, 我们先把最后一次遇到花并喝一斗酒的情况减去, 这样只需要计算李白遇到 5 次店, 9 次花, 并剩下了 1 斗酒有多少种情况就可以了, 正确的程序如下:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int ans=0; //定义全局变量用于计数

void f(int dian, int hua, int jiu){

/*模拟李白遇到店的情况
若要遇到店, 则剩下的店的数量必须大于 0
遇到店的时候, 剩下的花的数量不变但必须不为负数
遇到店之前不能把酒壶里面的酒喝成负数*/
		if(dian>0&&jiu>=0&&hua>=0){
			f(dian-1,hua,jiu*2);
		}

/*模拟李白遇到花的情况
若要遇到花, 则剩下的花的数量必须大于 0
遇到花的时候, 剩下的店的数量不变但必须不为负数
遇到花之前酒壶里面的酒至少要剩 1 斗以便于遇到花时喝*/		
		if(hua>0&&jiu>=1&&dian>=0){
			f(dian,hua-1,jiu-1);
		}

		if(dian==0&&hua==0&&jiu==1){
			ans++;
		}

	}

int main(){
	f(5,9,2);
	cout<<ans<<endl;
	system("pause");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

本题正确答案:
14

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/302684
推荐阅读
相关标签
  

闽ICP备14008679号