1 条题解
-
0
自动搬运
来自洛谷,原作者为

EnofTaiPeople
MGXS搬运于
2025-08-24 22:07:32,当前版本为作者最后更新于2021-08-08 15:33:01,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
AK 竞赛后发题解,RP++!
这是一道很好的小学数学题,能教会我们二次函数移动问题。
我花了半小时,A 了这道题,给大家讲讲做法。
对五个指令,我们进行分开处理:
指令 1、2:考察的是二次函数的移动法则:
左加右减,上加下减。
意思是,对一个二次函数(顶点式)
向左(右)移 会增加(减少);
向上(下)移 会增加(减少)。
于是上移代码如下:
scanf("%lf",&k1);c+=k1;右移有些复杂,步骤如下:
-
将函数转为顶点式
-
在顶点式进行右移操作
-
顶点式转为一般式
代码如下:
inline void rigt(ld a,ld &b,ld &c,ld w){ ld d=b/(2*a)-w,e=(4*a*c-b*b)/(4*a); c=e+d*d*a;b=d*2*a;return; }指令 3(有些麻烦,毕竟有 30% 数据没有指令 3)
这考察二次函数对称轴的转换和找特殊点。
对一个二次函数
一定有且仅有一个对称轴:
当函数图像关于点 进行对称变换时,有以下 3 个结论:
-
开口方向会变;
-
对称轴会对直线 进行对称变换;
-
函数中所有点都会关于点 进行对称变换。
所以,指令 3 步骤如下:
-
计算原对称轴;
-
计算新对称轴;
-
变为 ;
-
用新对称轴倒推得到 ;
-
因为当 时,,所以原函数过点 将 点关于 点进行对称变换,得到
由结论 3 可知, 在新函数图像上。
代码如下:
inline void CHS(ld &a,ld &b,ld &c,ld x1,ld y1){ ld zhou=-b/(2*a);a=-a; b=-(2*a)*(x1*2-zhou); ld x2=2*x1,y2=y1*2-c; c=y2-a*x2*x2-b*x2;return; }指令 4:求函数区间最值。
前置知识:对于二次函数
他在闭区间 的最值只会出现在 、 或顶点上。
所以,先判断顶点是否在闭区间 上,再求最值。
代码如下:
inline ld Min(ld a,ld b,ld c,ld k1,ld k2){ if(k1>k2)swap(k1,k2); ld dl=k1*k1*a+k1*b+c,dr=k2*k2*a+k2*b+c; ld dm=-b/(2*a),tans=min(dl,dr); if(dm>=k1&&dm<=k2) tans=min(tans,dm*dm*a+dm*b+c); return tans; } inline ld Max(ld a,ld b,ld c,ld k1,ld k2){ if(k1>k2)swap(k1,k2); ld dl=k1*k1*a+k1*b+c,dr=k2*k2*a+k2*b+c; ld dm=-b/(2*a),tans=max(dl,dr); if(dm>=k1&&dm<=k2) tans=max(tans,dm*dm*a+dm*b+c); return tans; }指令 5:这是除指令 1 之外最简单的了。
题意即
用左式减去右式,得到
注意到 ,问题转为求一元二次方程是否有解。
即判别式 是否非负。
代码如下:
inline int EJ(ld a,ld b,ld c,ld u,ld v,ld w){ a-=u;b-=v;c-=w; if(b*b>=4*a*c)return 2; else return 0; }综上,无注释 AC 代码:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; typedef double ld; inline void rigt(ld a,ld &b,ld &c,ld w){ ld d=b/(2*a)-w,e=(4*a*c-b*b)/(4*a); c=e+d*d*a;b=d*2*a;return; } inline void CHS(ld &a,ld &b,ld &c,ld x1,ld y1){ ld zhou=-b/(2*a); b=-(2*(a=-a))*(x1*2-zhou); ld x2=2*x1,y2=y1*2-c; c=y2-a*x2*x2-b*x2;return; } inline ld Min(ld a,ld b,ld c,ld k1,ld k2){ if(k1>k2)swap(k1,k2); ld dl=k1*k1*a+k1*b+c,dr=k2*k2*a+k2*b+c; ld dm=-b/(2*a),tans=min(dl,dr); if(dm>=k1&&dm<=k2) tans=min(tans,dm*dm*a+dm*b+c); return tans; } inline ld Max(ld a,ld b,ld c,ld k1,ld k2){ if(k1>k2)swap(k1,k2); ld dl=k1*k1*a+k1*b+c,dr=k2*k2*a+k2*b+c; ld dm=-b/(2*a),tans=max(dl,dr); if(dm>=k1&&dm<=k2) tans=max(tans,dm*dm*a+dm*b+c); return tans; } inline int EJ(ld a,ld b,ld c,ld u,ld v,ld w){ a-=u;b-=v;c-=w; if(b*b>=4*a*c)return 2; else return 0; } inline void gofans(){ ld a,b,c,k1,k2,u,v,w; int n,p;scanf("%lf%lf%lf%d",&a,&b,&c,&n); while(n--){ scanf("%d",&p); switch(p){ case 1:scanf("%lf",&k1);c+=k1;break; case 2:scanf("%lf",&k1);rigt(a,b,c,k1);break; case 3:scanf("%lf%lf",&k1,&k2); CHS(a,b,c,k1,k2);break; case 4:scanf("%lf%lf",&k1,&k2); printf("%.2lf %.2lf\n",Min(a,b,c,k1,k2),Max(a,b,c,k1,k2)); break;case 5:scanf("%lf%lf%lf",&u,&v,&w); printf("%d\n",EJ(a,b,c,u,v,w));break; default:while(true)printf("NO-ANSWER!\n");break; } } k1=-b/(2*a); printf("%.2lf\n",k1*k1*a+k1*b+c); return; } int main(){ int T;scanf("%d",&T); while(T--)gofans(); return 0; }完结撒花!
-
- 1
信息
- ID
- 4017
- 时间
- 1000ms
- 内存
- 250MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者