题目链接
https://code.google.com/codejam/contest/11274486/dashboard#s=p2
题意
给一个方程,求解
思路
二分
一时脑残写了个牛顿迭代,之前纠结于二分函数不一定单调,其实只要保证解单调即可:因为
r
在
牛顿迭代法
牛顿迭代法wiki
所以我们只需要去逼近解即可。
我们令
x=r+1
xn+1=xn+f(xn)f′(xn)
于是,计算出
f(xn)
和
f′(xn)
即可
代码
#include <bits/stdc++.h>
using namespace std;
inline int in() {int x; scanf("%d", &x); return x;}
#define pr(x) {cout << #x << ' ' << x << endl;}
#define LL long long
const int maxn = 105;
double c[maxn], a[maxn];
int n;
void read() {
n = in();
for (int i = 0; i <= n; i++) scanf("%lf", &c[i]);
c[0] = -c[0];
}
void get_derivative() {
for (int i = 0; i <= n; i++) {
a[i] = (double)(n - i) * c[i];
}
}
double quick_pow(double x, int n) {
double res = 1;
while (n) {
if (n & 1) res *= x;
x *= x;
n >>= 1;
}
return res;
}
double cal(double x, int sta) {
if (sta) {
double res = 0;
for (int i = 0; i < n; i++) {
res += a[i] * quick_pow(x, n - i - 1);
}
return res;
} else {
double res = 0;
for (int i = 0; i <= n; i++) {
res += c[i] * quick_pow(x, n - i);
}
return res;
}
}
double newton() {
double x = 2.0;
while (fabs(cal(x, 0)) > 1e-12) {
double t = x - cal(x, 0) / cal(x, 1);
if (x - t < 1e-10) return x - 1.0;
x = t;
}
return x - 1.0;
}
int main() {
int T = in(), kase = 0;
while (T--) {
read();
get_derivative();
double res = newton();
printf("Case #%d: %.12lf\n", ++kase, res);
}
return 0;
}