题目 | A | B | C |
---|---|---|---|
名称 | 一元三次方程求解 | 二分法求函数的零点 | 和为给定数 |
难度 | ☆☆☆★★ | ☆☆☆☆★ | ☆☆☆☆★ |
内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较
一本通 P 295 P295 P295,第 5 5 5题 有形如: a x 3 + b x 2 + c x + d = 0 ax^{3}+bx^{2}+cx+d=0 ax3+bx2+cx+d=0这样的一个一元三次方程。给出该方程中各项的系数( a , b , c , d a,b,c,d a,b,c,d均为实数),并约定该方程存在三个不同实根(根的范围在 − 100 -100 −100至 100 100 100之间),且根与根之差的绝对值 ≤ 1 \leq 1 ≤1。 要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 2 2 2位。
提示:记方程 f ( x ) = 0 f(x)=0 f(x)=0,若存在 2 2 2个数 x 1 x_1 x1和 x 2 x_2 x2,且 x 1 < x 2 x_1<x_2 x1<x2, f ( x 1 ) × f ( x 2 ) < 0 f(x1) \times f(x2)<0 f(x1)×f(x2)<0,则在 ( x 1 , x 2 ) (x1,x2) (x1,x2)之间一定有一个根。 输入: a , b , c , d a,b,c,d a,b,c,d 输出:三个实根(根与根之间留有空格)
四个实数 a , b , c , d a,b,c,d a,b,c,d
三个实根(根与根之间留有空格)
样例输入
1 -5 -4 20
样例输出
-2.00 2.00 5.00
Link
首先我们要定义
4
4
4个double
类型的变量:
a
,
b
,
c
,
d
a,b,c,d
a,b,c,d。
并将其输入。
double a, b, c, d; scanf ("%d %d %d %d", &a, &b, &c, &d);
check
函数check
函数就是把公式翻译成C++
代码。
f ( x ) = a x 3 + b x 2 + c x + d f(x)=ax^{3}+bx^{2}+cx+d f(x)=ax3+bx2+cx+d
注:函数的返回类型为double
double check (double x) { return a * x * x * x + b * x * x + c * x + d; }
就暴力枚举整数部分。(因为题目中已经说了每两个解的差超过 1 1 1,且二分查找每次只能查找一个数)
如果解就是整数,就直接输出。
若这两个数之间有解,就二分查找it
。
条件: if (check (i) * check (i + 1) < 0)
for (double i = ...(为了防止抄袭,这里不予显示); i < 100; i ++) { if (check (i) == 0) { printf ("%.2lf ", i); continue; } if (check (i) * check (i + 1) < 0) { double l = i, r = i + 1, mid; while (r - l > 0.001) { mid = (l + r) / 2; if (check (mid) * check (l) < 0) { r = mid; } else { l = mid; } } printf ("%.2lf ", mid); } }
注: 该AC代码仅供参考,请勿抄袭!
#include <cstdio> #include <algorithm> using namespace std; double a, b, c, d; double check (double x) { return a * x * x * x + b * x * x + c * x + d; } int main () { scanf ("%lf %lf %lf %lf", &a, &b, &c, &d); for (double i = ...(为了防止抄袭,这里不予显示); i < 100; i ++) { if (check (i) == 0) { printf ("%.2lf ", i); continue; } if (check (i) * check (i + 1) < 0) { double l = i, r = i + 1, mid; while (r - l > 0.001) { mid = (l + r) / 2; if (check (mid) * check (l) < 0) { r = mid; } else { l = mid; } } printf ("%.2lf ", mid); } } return 0; }
内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较
有函数:
f
(
x
)
=
x
5
−
15
x
4
+
85
x
3
−
225
x
2
+
274
x
−
121
f(x)=x^{5}-15x^{4}+85x^{3}-225x^{2}+274x-121
f(x)=x5−15x4+85x3−225x2+274x−121
。已知
f
(
1.5
)
>
0
,
f
(
2.4
)
<
0
f(1.5)>0,f(2.4)<0
f(1.5)>0,f(2.4)<0,且方程
f
(
x
)
=
0
f(x)=0
f(x)=0在区间
[
1.5
,
2.4
]
[1.5,2.4]
[1.5,2.4]有且只有一个根,请用二分法求出该根。
无。
该方程在区间 [ 1.5 , 2.4 ] [1.5,2.4] [1.5,2.4]中的根。要求四舍五入到小数点后 6 6 6位。
样例输入
无
样例输出
不提供
Link
check函数
check
函数就是把公式翻译成C++
代码。
f ( x ) = x 5 − 15 x 4 + 85 x 3 − 225 x 2 + 274 x − 121 f(x)=x^{5}-15x^{4}+85x^{3}-225x^{2}+274x-121 f(x)=x5−15x4+85x3−225x2+274x−121
注:函数的返回类型为double
double check (...(为了防止抄袭,这里不予显示) x) { return x * x * x * x * x - 15 * x * x * x * x + 85 * x * x * x - 225 * x * x + 274 * x - 121; }
double l = 1.5, r = 2.4;
2.二分查找it
。
注: 注意精度:1e-6
(保留6位小数)
此处不放代码,请读者独立完成。
#include <cstdio> #include <algorithm> using namespace std; double check (...(为了防止抄袭,这里不予显示) x) { return x * x * x * x * x - 15 * x * x * x * x + 85 * x * x * x - 225 * x * x + 274 * x - 121; } int main () { double l = 1.5, r = 2.4, mid; while (1) { mid = (l + r) / 2; if (check (mid) > -0.000001 && check (mid) < 0.000001) { printf ("%.6lf", mid); return 0; } else if (check (mid) > 0.000001) { l = ...(为了防止抄袭,这里不予显示); } else { r = mid; } } return 0; }
内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较
给出若干个整数,询问其中是否有一对数的和等于给定的数。
共三行:
第一行是整数 n ( 0 < n ≤ 1000000 ) n(0 < n \leq 1000000) n(0<n≤1000000),表示有 n n n个整数。
第二行是 n n n个整数。整数的范围是在 0 0 0到 1 0 8 10^{8} 108之间。
第三行是一个整数 m ( 0 ≤ m ≤ 2 30 ) m(0 \leq m \leq 2^{30}) m(0≤m≤230),表示需要得到的和。
输出格式
若存在和为
m
m
m的数对,输出两个整数,小的在前,大的在后,中间用单个空格隔开。若有多个数对满足条件,选择数对中较小的数更小的。若找不到符合要求的数对,输出一行No
。
样例输入
4 2 5 1 4 6
样例输出
1 5
新增 Hack
数据,暴力应该跑不过去了。
Link
首先定义两个变量 m , n m,n m,n以及一个整型数组 a a a
int m, n, a[...(为了防止抄袭,这里不予显示)]; scanf ("%d", &n); for (int i = 1; i <= n; i ++) { scanf ("%d", &a[i]); } scanf ("%d", &m);
首先暴力枚举较小数,剪枝: 若该数 > m 2 > \frac {m} {2} >2m
二分查找较大数。
此处不放代码,请读者独立完成。
#include <cstdio> #include <algorithm> using namespace std; int n, m, a[1000005]; int main () { scanf ("%d", &n); for (int i = 1; i <= n; i ++) { scanf ("%d", &a[i]); } sort (a + 1, a + n + 1); scanf ("%d", &m); for (int i = 1; i <= n; i ++) { if (a[i] > m / 2) break; int l = i + 1, r = n, mid; while (l <= r) { ...(为了防止抄袭,这里不予显示) } } printf ("No"); return 0; }