P9750 [CSP-J 2023] 一元二次方程

· · 题解

60分:
#include <bits/stdc++.h>
using namespace std;
int a,b,c,t,m;
int gcd(int a,int b){ return b ? gcd(b,a%b) : a; }
void you(int d){
    int p = -b+sqrt(d),w = -b-sqrt(d);//分子 
    int q = 2 * a;//分母 
    if(p*1.0/q < w*1.0/q) p = w;//取较大解
    if(p % q == 0 && w % q == 0){//如果整除 直接输出p/q 
        cout << p/q;
        return;
    }
    if((p<0 && q>0) || (p>0 && q<0)) cout << '-';//如果结果为负
    p = abs(p),q = abs(q);//取绝对值
    int k = gcd(p,q);//求最大公因数
    p /= k,q /= k;//约分
    if(q == 1) cout << p;//如果分母为1 直接输出分子
    else if(p == 0) cout << 0;//如果分子为0 直接输出0
    else cout << p << "/" << q; 
}
int f(int delta){//化简根号 
    int ans = 1;
    for(int i = 2;i <= sqrt(delta);i++){
        while(delta % (i*i) == 0){//倍数 
            ans *= i;
            delta /= i*i;//分解完全平方数 
        }
    }
    return ans;
}
void wu(int delta){
    if(-b * 1.0/(2*a)){//if q1!=0
        you(0);//按有理数输出
        cout << "+";//输出一个+ 
    }
    int k = f(delta);
    delta /= k*k;
    double q2 = fabs(1.0*k/(2*a));//计算q2
    if(q2 == 1) printf("sqrt(%d)",delta);//直接省略 
    else if(q2 == floor(1/q2) && 1/q2!=0) printf("sqrt(%d)/%.0f",delta,1/q2);
    else{
        int c = k,d = 2*a,x = gcd(c,d);
        c /= x,d /= x;
        if((c<0 && d>0) || (c>0 && d<0)) c = abs(c),d = abs(d);
        if(c!=1) cout << abs(c) << '*';
        printf("sqrt(%d)/%d",delta,d);
    } 
    cout << endl;
}
int main(){
    cin >> t >> m;
    while(t--){
        cin >> a >> b >> c;
        if(a < 0) a = -a,b = -b,c = -c;//分母非负 
        int delta = b * b - 4 * a * c,k = 1;//判别式
        if(delta < 0) cout << "NO\n";
        else{
            if(sqrt(delta) == floor(sqrt(delta))){//按照有理数输出 
                you(delta);
                cout << '\n';
            }else wu(delta);//按照无理数输出           
        } 
    }
    return 0;
}