问题 1004: [递归]母牛的故事
时间限制: 1Sec 内存限制: 128MB 提交: 23933 解决: 6874
题目描述
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
输入
输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。
n=0表示输入数据的结束,不做处理。
输出
对于每个测试实例,输出在第n年的时候母牛的数量。
每个输出占一行。
样例输入
2
4
5
0
样例输出
2
4
6
题解:
很像一道找规律题,然后递归求解即可。
以零退出可以在while循环直接放上cin>>n&&n!=0的条件即可。
第n年: 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9
fn头牛: 1 ,2 ,3 ,4 ,6 ,9 ,13 ,19 ,28
n=1,2,3时,fn=1,2,3
n>3时,fn=f(n-1)+f(n-3)
解法一:递归
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
//k=1,2,3时,fn=1,2,3
//k>3时,fn=f(n-1)+f(n-3);
int i,n,j;
int a[100];
int f(int k)
{
if(k<=3)
{
return k;
}
return f(k-1)+f(k-3);
}
int main()
{
while(cin>>n&&n!=0)
{
a[i++]=n;
}
for(j=0;j<i;j++)
{
cout<<f(a[j])<<endl;
}
return 0;
}
解法二:迭代
迭代4到n次才能迭代到目标,相当于递归,但是递归为调用函数,耗时。
循环一次,三个数据都向后挪一位,相当于进行了一次递归。画个图或许好理解一点。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
//k=1,2,3时,fn=1,2,3
//k>3时,fn=f(n-1)+f(n-3);
int main()
{
int f1=1,f2=2,f3=3,fn;
int n,i;
while(cin>>n&&n!=0)
{
f1=1,f2=2,f3=3;
if(n<=3)
cout<<n<<endl;
else
{
for(i=4;i<=n;i++)//迭代4到n次才能迭代到目标,相当于递归,
{ //但是递归为调用函数,耗时。
fn=f3+f1;
f1=f2;
f2=f3;
f3=fn;
}
cout<<fn<<endl;
}
}
return 0;
}
问题 1018: [编程入门]有规律的数列求和
时间限制: 1Sec 内存限制: 128MB 提交: 5283 解决: 3726
题目描述
有一分数序列: 2/1 3/2 5/3 8/5 13/8 21/13… 求出这个数列的前N项之和,保留两位小数。
输入
N
输出
数列前N项和
样例输入
10
样例输出
16.48
**题解:**分子和分母都是前两项的和,直接写就行了,注意要用double,输出用printf来控制最后的小数位数。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
double f(int k)
{
double a[100],b[100];
double result=0;
int i=0;
a[0]=2;b[0]=1;
while(i<k)
{
result+=(a[i]/b[i]);
i++;
if(i==1)
{
a[i]=a[i-1]+1;
b[i]=b[i-1]+1;
}
else
{
a[i]=a[i-2]+a[i-1];
b[i]=b[i-2]+b[i-1];
}
}
return result;
}
int main()
{
int n;
cin>>n;
printf("%.2f\n",f(n));
return 0;
}
问题 1072: 汽水瓶
时间限制: 1Sec 内存限制: 128MB 提交: 3520 解决: 1707
题目描述
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
输入
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。
输出
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
样例输入
3
10
81
0
样例输出
1
5
40
题解:其实就是取除数和取余数,除数和余数相加就是此时的剩余瓶盖,然后进行条件判断,为2时,小于2时,大于3时则再次进入递归函数。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int num=0;
int f(int k)//k=10
{
int b,d,e;
b=k/3;
d=k%3;
e=b+d;
num+=b;
if(e==2||e==3)
{
num++;
return num;
}
if(e<2)
{
return num;
}
if(e>3)
{
f(e);
}
return num;
}
int main()
{
int a[100];
int n,i=0,j;
int c;
while(cin>>n)
{
if(n==0)
break;
a[i++]=n;
}
for(j=0;j<i;j++)
{
cout<<f(a[j])<<endl;
num=0;
}
return 0;
}
问题 1073: 弟弟的作业
时间限制: 1Sec 内存限制: 128MB 提交: 2391 解决: 1075
题目描述
你的弟弟刚做完了“100以内数的加减法”这部分的作业,请你帮他检查一下。每道题目(包括弟弟的答案)的格式为a+b=c或者a-b=c,其中a和b是作业中给出的,均为不超过100的非负整数;c是弟弟算出的答案,可能是不超过200的非负整数,也可能是单个字符"?",表示他不会算。
输入
输入文件包含不超过100行,以文件结束符结尾。每行包含一道题目,格式保证符合上述规定,且不包含任何空白字符。输入的所有整数均不含前导0。
输出
输出仅一行,包含一个非负整数,即弟弟答对的题目数量。
样例输入
1+2=3
3-1=5
6+7=?
99-0=99
样例输出
2
题解:定义五个变量输入int char int char char,判断+还是-,分别处理,将char类型的结果转化为int型才能比较,这里用到了atoi函数,用法:char str[20]; atoi(str);可以将char型数组转化为整型,若定义的是string类型,则要用到string类型的函数c_str()函数,可以将string转化为char,再通过atoi将char型转化为int型进行比较。用法:string str;atoi(str.c_str());注意用到了continue,不是break。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int a,b,s;
char c,d;
int num=0;
char str[30];
while(cin>>a>>c>>b>>d>>str)
{
if(c=='+')
{
if(str[0]=='?')
continue;
s=atoi(str);
if(a+b==s)
num++;
}
if(c=='-')
{
if(str[0]=='?')
continue;
s=atoi(str);
if(a-b==s)
num++;
}
}
cout<<num<<endl;
return 0;
}
问题 1093: 字符逆序
时间限制: 1Sec 内存限制: 64MB 提交: 7440 解决: 3710
题目描述
将一个字符串str的内容颠倒过来,并输出。str的长度不超过100个字符。
输入
输入包括一行。 第一行输入的字符串。
输出
输出转换好的逆序字符串。
样例输入
I am a student
样例输出
tneduts a ma I
题解:本题简单,但有一个重点,输入数据有空格,cin和scanf都无法读入空格,所以要用getline,样例:getline(cin,str);
然后调用string的函数length()来计算长度,然后倒序输出。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string str;
int i;
getline(cin,str);
for(i=str.length()-1;i>=0;i--)
{
cout<<str[i];
}
return 0;
}
问题 1107: 纪念品分组
时间限制: 1Sec 内存限制: 128MB 提交: 438 解决: 136
题目描述
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入
输入包含n+2行:
第1行包括一个整数w,为每组纪念品价格之和的上眼= 第2行为一个整数n,表示购来的纪念品的总件数G
第3-n+2行每行包含一个正整数Pi (5 <= Pi <= w3)w表示所对应纪念品的价格。
输出
输出仅一行,包含一个整数, ep最少的分组数目合
样例输入
100
9
90
20
20
30
50
60
70
80
90
样例输出
6
题解:本题不难,就是两个数要凑成w,抽成一对就num++;大于w则num++;向前移动;
用两层for循环,一个从前往后,一个从后往前,两头并进,(a[j]+a[i])>w时num++,continue;继续向前找相加起来小于等于w的,找到后跳出第二层循环,i++继续后移,继续进入,用pos标记目前从后往前用过的数据,标记为此次循环用过的最后一个位置,下一次循环则从pos的前一个位置开始向前,直到i==j即i与j碰面时退出第二层循环,接着退出第一层循环,输出num;
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int w,n,i,j;
int num=0,pos;
int a[30005];
cin>>w>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
pos=n;
sort(a,a+n);//sort排序
for(i=0;i<n;i++)
{
for(j=pos-1;j>=i;j--)//20 20 30 50 60 70 80 90 90
{
if(i==j)
{
num++;
break;
}
if((a[j]+a[i])>w)
{
num++;
continue;
}
else
{
num++;
pos=j;
break;
}
}
if(i==j)
break;
}
cout<<num<<endl;
return 0;
}
问题 1116: IP判断
时间限制: 1Sec 内存限制: 128MB 提交: 2732 解决: 1076
题目描述
在基于Internet的程序中,我们常常需要判断一个IP字符串的合法性。
合法的IP是这样的形式:
A.B.C.D
其中A、B、C、D均为位于[0, 255]中的整数。为了简单起见,我们规定这四个整数中不允许有前导零存在,如001这种情况。
现在,请你来完成这个判断程序吧_
输入
输入由多行组成,每行是一个字符串,输入由“End of file”结束。
字符串长度最大为30,且不含空格和不可见字符
输出
对于每一个输入,单独输出一行
如果该字符串是合法的IP,输出Y,否则,输出N
样例输入
1.2.3.4
a.b.c.d
267.43.64.12
12.34.56.bb
210.43.64.129
-123.4.5.6
样例输出
Y
N
N
N
Y
N
题解:用string类型输入,先判断有无字母,有的话直接输出N;没有的话在将0-第一个点进行切割,判断是否满足题目条件,继续切割两个逗号之间,切两次,现在切了三次,最特别的单独考虑:(就是最后一次)要从上一个点的下一个位置截取需要截到最后一个元素的下一个位置。一共四次。
学到的东西:用到了 ,string的构造函数 string( string &str, size_type index, size_type length ); 从str中取,以index为下标开始,截取长度为length结束。
eg: string str;
int index=1,length=5;
string str1(str,index,length);
解释:从str字符串中以1为下标开始截取长度为五的字串,将截取到的字符串存到str1中。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string str;
char c;
int len,i;
while(getline(cin,str))//267.43.64.12
{
int flag=0;//截取部分的开始flag 截取部分的结束i-flag
int k=1;//判断是否有字母(0,1)
len=str.length();
c='Y';
for(i=0;i<len;i++)
{
if(str[i]=='.')//把点先跳过
continue;
if(str[i]<'0'||str[i]>'9')//判断字母
{
c='N'; break;k=0;
}
}
if(k)//没有字母再判断
{
int num;
for(i=0;i<len;i++)
{
if(str[i]=='.'||i==len-1)//共有三个点,if条件会进入3+1次//此时i为点的位置和最后一个元素的位置
{
//string 类型的构造函数
//string( string &str, size_type index, size_type length );
//从str中取,以index为下标开始,截取长度为length结束。
if(i==len-1)//i为最后一个元素的位置时。此处特殊,单独处理。
{
string strtemp1(str,flag,i-flag+1);//截取最后一个逗号位置的下一个位置和最后一个元素的下一个位置之间
num=atoi(strtemp1.c_str());//将string转化为char再转化为int
}
else
{
string strtemp2(str,flag,i-flag);//截取0-逗号之前 截取两个逗号之间
num=atoi(strtemp2.c_str());
}
if(num>255||num<0)
{
c='N';break;
}
flag=i+1;//指向上一个.的下一个位置
}
}
}
cout<<c<<endl;//输出
}
return 0;
}
问题 1199: 哥德巴赫曾猜测
时间限制: 1Sec 内存限制: 128MB 提交: 577 解决: 304
题目描述
德国数学家哥德巴赫曾猜测:任何大于6的偶数都可以分解成两个素数(素数对)的和。但有些偶数可以分解成多种素数对的和,如: 10=3+7,10=5+5,即10可以分解成两种不同的素数对
输入
输入任意的>6的正偶数(<32767)
输出
试求给出的偶数可以分解成多少种不同的素数对(注: A+B与B+A认为是相同素数对)
样例输入
1234
样例输出
25
题解:a+(n-a)=n就是判断a和n-a是否是质数,写一个函数即可。同时要保证没有重复,只需保证a<=n-a即可;
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int f(int a)
{
int i,j;
if(a==1||a==0)
return 0;
for(i=2;i*i<=a+1;i++)
{
if(a%i==0)
return 0;
}
return 1;
}
int main()
{
int num=0;
int i;
cin>>n;
for(i=2;i<n&&(n-i)>=0;i++)
{
if(f(i)&&f(n-i)&&i<=n-i)
{
num++;
}
}
cout<<num<<endl;
return 0;
}