2018年东北农业大学春季校赛 A-wyh的曲线
链接:https://www.nowcoder.com/acm/contest/93/A
来源:牛客网
题目描述
给你三组数列,分别为
现在给你一个式子:
然后我们可以将这个函数画在一个xoy直角坐标系下,x的范围为[0,100],当然我们可以得到一条曲线,现在你们涵哥让你们求出这个曲线的长度,结果保留两位小数
输入描述:
单组输入:
每组测试数据第一行输入一个整数n。
接下来n行,每行3个数代表
Data limit:
输出描述:
对于每组测试数据,输出对应答案,结果保留两位小数
示例1
输入
3
1 2 3
4 5 6
7 8 9
输出
215.56
思路
此题先考虑高等数学所学知识,定积分求平面曲线的弧长(第二类曲线积分)。由于存在上限100.0,可能不是一段“光滑”的圆弧,会有些麻烦,一直AC不过。
赛后看别人的提交,发现题目描述有误。压根就不是(cin >> a >> b >> k;),而是 cin >> k >> a >> b;
(能AC就有鬼了。。。)
AC代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
int n;
vector<double> ai,bi,ki;
double getY(double x){
double minY = 100.0;
for(int i=0; i<n; i++){
double y = (ki.at(i))*(x-ai.at(i))*(x-ai.at(i))+bi.at(i);
minY=min(minY,y);
}
return minY;
}
double Total(double left, double right){
double mid = (left+right)/2.0;
if(right-left > 1e-4){
return Total(left,mid) + Total(mid,right);
}
double y_left = getY(left);
double y_right = getY(right);
double y_mid = getY(mid);
double dy0 = y_right-y_left, dy1 = y_mid-y_left, dy2 = y_right-y_mid;
double dx0 = right-left, dx1 = mid-left, dx2 = right-mid;
double d0 = sqrt(dx0*dx0+dy0*dy0);
double d1 = sqrt(dx1*dx1+dy1*dy1);
double d2 = sqrt(dx2*dx2+dy2*dy2);
if(fabs(d2+d1-d0) < 1e-9){
return d0;
}else{
return Total(left,mid) + Total(mid,right);
}
}
int main()
{
ios::sync_with_stdio(false); // 需加上,否则会超时
cin >> n;
// while(n--){
for(int i=0;i<n;i++){
double a,b,k;
// cin >> a >> b >> k;
cin >> k >> a >> b;
ai.push_back(a);
bi.push_back(b);
ki.push_back(k);
}
double ans = Total(0, 100);
cout << fixed << setprecision(2) << ans << endl;
return 0;
}