算法训练 调和数列问题
Description
输入一个实数x,求最小的n使得,1/2+1/3+1/4+...+1/(n+1)>=x。
输入的实数x保证大于等于0.01,小于等于5.20,并且恰好有两位小数。你的程序要能够处理多组数据,即不停地读入x,如果x不等于0.00,则计算答案,否则退出程序。
输出格式为对于一个x,输出一行n card(s)。其中n表示要计算的答案。
Input
输入描述:
分行输入x的具体数值
输入样例:
1.00
3.71
0.04
5.19
0.00
Output
输出描述:
分行输出n的数值,格式为n card(s)
输出样例:
3 card(s)
61 card(s)
1 card(s)
273 card(s)
Hint
HINT:时间限制:1.0s 内存限制:512.0MB
Source
蓝桥杯练习系统 ID: 107 原题链接: http://lx.lanqiao.cn/problem.page?gpid=T107
Thought
因为本题是多次输入求值,不是求一次的事情,所以考虑先生成一个调和数列,然后二分查找。
学习使用两个库函数:lower_bound( ) 和 upper_bound( )
lower_bound( begin, end, num):二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin得到找到数字在数组中的下标。
upper_bound( begin, end, num):二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
lower_bound( begin, end, num, greater
() ):二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater
() ):二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
Submit
#include <iostream>
#include <map>
using namespace std;
int main() {
map<double, int> sequence; //前一个是n值下的和,后一个是n值
double s=0;
for(int i=1; s<=5.20; i++) { //生成调和数列
s += 1.0/(i+1);
sequence[s]=i;
}
double x;
map<double, int>::iterator iter;
while(cin>>x, x!=0.00) { //先执行输入,再执行判断
iter = sequence.lower_bound(x);
cout<< iter->second <<" card(s)"<<endl;
}
return 0;
}
浙公网安备 33010602011771号