问题 G: 汽水瓶 时间限制: 1 Sec 内存限制: 128 MB 提交: 93 解决: 45 201501010119 提交状态讨论版 题目描述 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝? 输入 输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。 输出 对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。 样例输入 Copy 3 10 81 0 样例输出 Copy 1 5 40
看样例:输入10,9个瓶子换三瓶可以喝的汽水=》n=10/3=3; 现有的空瓶子=喝掉的三瓶(变为空瓶子)+剩下的一个空瓶=》10/3+10%3=4;四个空瓶子取三个还可以换饮料,发现回到了最初的步骤:拥有的空瓶子数量/3;
直到拥有的空瓶子剩下两个,向老板接借一个(+1),除以3就兑换完汽水啦~
其实吧,想要更简单的代码就直接观察样例,发现答案就是输入的n除以2(当然是计算机里的整除)
#include <bits/stdc++.h> using namespace std; int main() { int n; //空瓶子的数量 while(scanf("%d",&n)&&n) { int a; //喝的汽水数量 a=0; //注意归零 while(n>1) //空瓶子大于等于2可以换汽水 { a=a+n/3; //喝的汽水+空瓶子换的汽水 n=n%3+n/3; //上次换汽水剩下的瓶子+空瓶子换的汽水(喝完了就变成空瓶子了) if(n==2) //特殊情况,每次循环判断一次 n++; } cout<<a<<endl; } return 0; }
问题 H: 蜂房 时间限制: 1 Sec 内存限制: 128 MB 提交: 1 解决: 1 201501010119 提交状态讨论版 题目描述 有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。 其中,蜂房的结构如下所示。 (咳咳,图不见了) 输入 多组数据输入,每组数据包含两个正整数a, b,且 a<b。 输出 蜜蜂从蜂房a爬到蜂房b的可能路线数。 样例输入 Copy 1 2 3 4 样例输出 Copy 1 1
一、a->b的路径可以化归于1->(b-a)的路径情况
因为不能反向爬行,且只能爬右侧相邻蜂房,所以决定了可以化归的特殊性(老师上课也讲过了)
二、递归的思想
假设1->5,反过来看:到达5有两个选择,从3到达,或者从4到达,所以这个数量是由前面两种情况决定的;那么到达3也有两种情况,要么从1要么从2;到达4同理;
所以我们得到一个规律,要到达的目的地数量由前两种方法决定;
所以这也是递归的核心;
而递归的终止条件是:1->1;1->2;1->3;
#include <bits/stdc++.h> using namespace std; int f(int n) { if(n<4) //基本条件 return n; else { return f(n-1)+f(n-2); //递归表达式 } } int main() { int a,b; while(scanf("%d%d",&a,&b)!=EOF) { int n; n=b-a; cout<<f(n)<<endl; } return 0; }
问题 K: 骨牌覆盖 时间限制: 1 Sec 内存限制: 128 MB 提交: 0 解决: 0 201501010119 提交状态讨论版 题目描述 用大小为1×2的骨牌铺满一个大小为2×n的长方形方格,编写一个程序,输入n,输出铺放方案总数。例如,输入n=3,即大小为2×3的方格,输出3。3种骨牌铺放方案如下图所示: 输入 多组测试用例,每一组是一个正整数。 输出 每组输出占一行。 只需要输出铺放方案总数,不需要输出具体的铺放方案。 样例输入 Copy 3 样例输出 Copy 3
这个题和上一题代码其实差不多,主要也是找规律得到递推式
n=1,n=2,n=3是可以直接得到的(已知条件);
从第四块开始,放的砖块有两种情况了,要么横着放要么竖着放,
横着放有两种放法,也就是f(2);
竖着放就只有一种放法,f(3);
两种放法加起来就是f(4);
以此类推,每个n的方法都是建立在两种情况下的,而每种情况又可以追溯到最初的已知条件,所以就直接递归咯
#include <bits/stdc++.h>
using
namespace
std;
int
f(
int
n)
{
if
(n<=3) //已知条件
return
n;
else
return
f(n-1)+f(n-2); //递归式,两种情况
问题 I: 倒序输出 时间限制: 1 Sec 内存限制: 128 MB 提交: 0 解决: 0 201501010119 提交状态讨论版 题目描述 使用递归编写一个程序,逆序输出一个正整数。例如输入1234,输出4321。 输入 多组输入,每组输入一个正整数。 输出 逆序输出结果,每个结果占一行。 样例输入 Copy 12 1234 样例输出 Copy 21 4321
#include <bits/stdc++.h> using namespace std; void f(int n) //递归函数 { int a; //用来存放数的个位 int s=0; if(n==0) return ; else { a=n%10; //分离个位 cout<<a; f(n/10); //去掉个位,再次递归,输出高位
问题 J: 递归求和 时间限制: 1 Sec 内存限制: 128 MB 提交: 0 解决: 0 201501010119 提交状态讨论版 题目描述 使用递归编写一个程序,计算一个正整数中所有数字之和。例如输入234,输出9 输入 多组输入,每组输入一个正整数。 输出 输出结果,每个结果占一行。 样例输入 Copy 234 样例输出 Copy 9
#include <bits/stdc++.h> using namespace std; int f(int n) {if(n==0) return 0; else { return (n%10+f(n/10)); //分离数的各个位并且加起来并且进入下一次递归 } } int main() { int n; while(scanf("%d",&n)!=EOF) { cout<<f(n)<<endl; } return 0; }
} } int main() { int n; while(scanf("%d",&n)!=EOF) { f(n); cout<<endl; } return 0; }
}
int
main()
{
int
n;
while
(
scanf
(
"%d"
,&n)!=EOF)
{
int
s;
s=f(n);
cout<<s<<endl;
}
return
0;
}