本文最后更新于 2024年8月6日 晚上
此题为CSP-J 2023 第三题一元二次方程。题目传送门
题面解释
这道题是让求一个一元二次方程的较大实数根,并按照题目指定的方法进行输出。
一元二次方程
首先需要先了解一下一元二次方程,题目中采用公式法来解方程。一元二次方程的一般形式为
,系数为 , , 代入至
判断根的情况,如果有实数根则代入至
求出根。
题目有理数输出格式
一个有理数
将其约分至最简,如果可以整除输出p
,否则输出p/q
解方程
解方程需要分为几步。首先判断根的情况,再判断根是有理数还是无理数,最后进行输出。
方程无实数根
即
无实数根,输出NO
方程有两个相等的实数根
即 方程的根为
进行约分,根据有理数输出格式输出即可
方程有两个不等的实数根
即 方程的根为
,
由于 a
的正负不确定所以无法确定较大根是哪一种式子,所以需要在一开始就判断 a
的正负,如果 a 为负数,那么就将系数全部取反(这样不影响结果)。这样
便是较大根。接下来判断
是否为有理数,有理数则约分输出;无理数则需要将式子转化为 ,首先可以知道 ,然后将 分解为 的结构,然后开出 ,所以 。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include<bits/stdc++.h> using namespace std; int T,M,a,b,c,t,fz,fm,st,x,r; void YueFen() { int flag=0; if(fz<0) flag=1,fz=-fz; int temp=__gcd(fz,fm); fz/=temp,fm/=temp; if(flag) fz=-fz; } void x2r() { for(int i=sqrt(t);i>=1;i--) { int temp=t/(i*i); if(temp*(i*i)==t){ x=i,r=temp; return; } } } int main() { cin>>T>>M; while(T--) { cin>>a>>b>>c; if(a<0) a=-a,b=-b,c=-c; t=b*b-4*a*c; if(t<0) { cout<<"NO"<<endl; } else if(t==0) { fz=-b,fm=2*a; YueFen(); if(fm==1) cout<<fz<<endl; else cout<<fz<<'/'<<fm<<endl; } else { st=sqrt(t); if(st*st==t) { fz=-b+st,fm=2*a; YueFen(); if(fm==1) cout<<fz<<endl; else cout<<fz<<'/'<<fm<<endl; } else { if(b!=0) { fz=-b,fm=2*a; YueFen(); if(fm==1) cout<<fz<<'+'; else cout<<fz<<'/'<<fm<<'+'; } x2r(); fz=x,fm=2*a; YueFen(); if(fz==fm) cout<<"sqrt("<<r<<')'<<endl; else if(fm==1) cout<<fz<<"*sqrt("<<r<<')'<<endl; else if(fz==1) cout<<"sqrt("<<r<<")/"<<fm<<endl; else cout<<fz<<"*sqrt("<<r<<")/"<<fm<<endl; } } } return 0; }
|