题解 P5139 【z小f的函数】
Content
给定
- 操作
1 :给定k ,将函数图像向上移动k 格(k<0 就是向下移动-k 格)。 - 操作
2 :给定k ,将函数图像向右移动k 格(k<0 就是向左移动-k 格)。 - 操作
3 :给定k_1,k_2 ,将函数图像关于点(k_1,k_2) 对称。 - 操作
4 :给定k_1,k_2 ,求函数图像在闭区间[k_1,k_2] 内的最大值和最小值并输出(保留2 位小数)。 - 操作
5 :给定u,v,w ,求y=ax^2+bx+c 的函数图像是否和y=ux^2+vx+w 的函数图像有焦点,有的话输出2,否则输出0。
在所有操作弄完以后,你还需要给出操作完以后函数的最值(显然,根据
Range
- 关于
T,m ,有T\leqslant 10,m\leqslant 10000 。 - 关于其他的变量,保证
a\neq0,u\neq0,a\neq u,1\leqslant p\leqslant5,-100\leqslant a,b,c,k_1,k_2,k,u,v,w\leqslant 100 。
Gossip
看完这道题目,我突然回到了初二下学期那段被二次函数支配的时光。我仍然还记得那一条条流动的抛物线……
于是,我拿出了那时候的斗志,开始做这道题目。
Solution
我使用的是一般式进行操作。这么做的优点是,你不需要花多余的时间来求顶点式
话不多说,开始处理每个操作:
Part 1 操作 1
很显然,我们将其上下移动以后改变的只是常数项的值。
什么什么,你还要我讲原因?
那就请看图吧:
上图中蓝色的曲线是函数
或者我们也可以这样:
设
令两个函数的
本来这个很显然的,但我想为了照顾那些还没有学二次函数的学弟,所以还是写写吧。
故,操作后的函数为
Part 2 操作 2
这个用顶点式的话很方便,但是我们这里只提一般式的做法,不过会借用一下顶点式。
首先,我们可以由顶点式
故,操作后的函数为
Part 3 操作 3
首先,我们令一个在抛物线上的点为
什么什么,要我讲原因?
可以,那请听我说:由于它们的横坐标和纵坐标之差分别为
那么我们再代入到
那么再对右边的式子进行化简,然后再合并
故,操作后的函数为
Part 4 操作 4
这一段是我们的重头戏。
首先根据
笔者温馨提示:自己画一个函数图像具体分析,下面的两个图中作为例子的函数解析式左边有。
好的,那么现在就开始吧。
4.1 a<0
那么这时候还需要
4.2 a>0
同样,这时候还需要
至此,所有的分类讨论就完了,直接判断条件对应输出结果就好。
Part 5 操作 5
这个倒比操作
我们将上面这个方程移项,可以得到
当
至此,用一般式解决本题的算法也就讲完了。顶点式的话题解区里的大佬们已经讲得很清楚了。
如有不懂的话,下面的代码也许能帮助你。
Code
#include <cstdio>
#include <algorithm>
using namespace std;
int t;
double f(double a, double b, double c, double x) {
return a * x * x + b * x + c;
}
int main() {
scanf("%d", &t);
while(t--) {
double a, b, c;
int m;
scanf("%lf%lf%lf%d", &a, &b, &c, &m);
while(m--) {
int opt;
scanf("%d", &opt);
if(opt == 1) {
double k;
scanf("%lf", &k);
double a0 = a, b0 = b, c0 = c + k;
a = a0, b = b0, c = c0;
}
else if(opt == 2) {
double k;
scanf("%lf", &k);
double a0 = a, b0 = b - 2 * a * k, c0 = a * k * k - b * k + c;
a = a0, b = b0, c = c0;
}
else if(opt == 3) {
double k1, k2;
scanf("%lf%lf", &k1, &k2);
double a0 = -a, b0 = 4 * a * k1 + b, c0 = 2 * k2 - 4 * a * k1 * k1- 2 * b * k1 - c;
a = a0, b = b0, c = c0;
}
else if(opt == 4) {
double k1, k2, xp = -(b / (2 * a)), yp = (4 * a * c - b * b) / (4 * a);
scanf("%lf%lf", &k1, &k2);
if(a > 0) {
if(k2 < xp) {
printf("%.2lf %.2lf\n", f(a, b, c, k2), f(a, b, c, k1));
}
else if(k1 < xp) {
if(k2 - xp < xp - k1) {
printf("%.2lf %.2lf\n", f(a, b, c, xp), f(a, b, c, k1));
}
else if(k2 - xp >= xp - k1) {
printf("%.2lf %.2lf\n", f(a, b, c, xp), f(a, b, c, k2));
}
} else {
printf("%.2lf %.2lf\n", f(a, b, c, k1), f(a, b, c, k2));
}
} else if(a < 0) {
if(k2 < xp) {
printf("%.2lf %.2lf\n", f(a, b, c, k1), f(a, b, c, k2));
}
else if(k1 < xp) {
if(k2 - xp < xp - k1) {
printf("%.2lf %.2lf\n", f(a, b, c, k1), f(a, b, c, xp));
}
else if(k2 - xp >= xp - k1) {
printf("%.2lf %.2lf\n", f(a, b, c, k2), f(a, b, c, xp));
}
} else {
printf("%.2lf %.2lf\n", f(a, b, c, k2), f(a, b, c, k1));
}
}
}
else if(opt == 5) {
double u, v, w;
scanf("%lf%lf%lf", &u, &v, &w);
double delta = (b - v) * (b - v) - 4 * (a - u) * (c - w);
puts(delta < 0 ? "0" : "2");
}
}
printf("%.2lf\n", (4 * a * c - b * b) / (4 * a));
}
return 0;
}