20240321每日一题题解
20240321每日一题题解
Problem
已知 \(f(x,n)=\sqrt{n+\sqrt{(n-1)+\sqrt{(n-2)+\sqrt{...+2+\sqrt{1+x}}}}}\)。
计算 \(f\) 的值。
输入 \(x\) 和 \(n\)。输出这个函数值,并且注意需要保留两位小数。
例如,输入4.2 10,则应该输出3.68
Solution
递归?循环?
说实话这道题是有一定思考量的,初看可能会无从下手。
可以得出普遍结论:
如此,就可以依照我们昨天的递归来解决了。
当然,也可以用循环解决这道题。
我们从内部向外剖析:
这个函数的最内层是\(\sqrt{1+x}\),而后再给\(\sqrt{1+x}\)加上了\(2\),再套了根号;再加上了\(3\),再套了根号;再加上了\(4\),再套了根号;……;再加上了\((n-1)\),再套了根号;再加上了\(n\),再套了根号。
所以可以用写成for循环的格式,每次给答案执行+i再套根号,边界是i<=n。
保留两位小数
c++中有两种保留两位小数的方法,分别是给cout的printf使用的。
虽然老师上课说
printf是c的,其实c++中依然可以使用printf,其在头文件cstdio当中,完完全全可以正常使用。我认为其也是c++不可或缺的一部分。
cout
默认情况下,cout使用 6 个有效数显示浮点值,其余自动四舍五入,有后缀0则会自动舍去。
使用 cout<<fixed<<setprecision(2)来控制接下来输出的小数位数,括号里是几就保留几位小数。
这个函数在头文件#include<iomanip>中。
printf
这个可以类比python中的%格式符:
printf("%.2lf\n",f(x,n));表示保留小数点后两位。
Code
递归写法
#include<iostream>
#include<cmath>//使用sqrt
#include<iomanip>//cout的setprecision控制小数位数
#include<cstdio>//使用printf
using namespace std;
double f(double x,int n)
{
if(n==1)
{
return sqrt(1+x);
}
return sqrt(n+f(x,n-1));
}
int main()
{
double x;
int n;
cin>>x>>n;
cout<<fixed<<setprecision(2)<<f(x,n)<<endl;
// printf("%.2lf\n",f(x,n));
return 0;
}
循环写法
#include<iostream>
#include<cmath>//使用sqrt
#include<iomanip>//cout的setprecision控制小数位数
#include<cstdio>//使用printf
using namespace std;
int main()
{
double x;
int n;
cin>>x>>n;
double ans=x;
for(int i=1;i<=n;i++)
{
ans=sqrt(i+ans);
}
cout<<fixed<<setprecision(2)<<ans<<endl;
// printf("%.2lf\n",f(x,n));
return 0;
}
AC
