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

思路

大模拟,按照题意模拟即可。

首先按照 Δ 的取值分为 3 类:

  1. Δ<0

  2. Δ=0

  3. Δ>0

对于第 1 种情况,根据题意,输出 NO

对于第 2 种情况,原方程只会有一个解为 b2a,求一个 gcd 约分即可。

对于第 3 种情况,原方程会有两个解 b±×Δ2a,此时我们可以得到此时取 更优,还是取 + 更优。在这里我们定义 w=1/1 表示在原方程中取 / + 更优。

然后化简 Δ 为一个 pair t,表示 t1t2 并且满足 t2 最简。

t2 的取值也分为 2 种情况:

  1. t2=1

  2. t21

对于第 1 种情况,答案为 b+w×t12a

对于第 2 种情况,由于 b2a 有可能为 0,所以需要单独判断一下即可。

Code

#include <bits/stdc++.h>  
#define fst first  
#define snd second  
#define re register  
#define int long long  
#define double long double  
  
using namespace std;  
  
typedef pair<int,int> pii;  
const double eps = 1e-5;  
int T,lim,a,b,c;  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 1) + (r << 3) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline int gcd(int a,int b){  
    if (!b) return a;  
    return gcd(b,a % b);  
}  
  
inline int qmi(int a,int b){  
    int res = 1;  
    while (b){  
        if (b & 1) res *= a;  
        a *= a;  
        b >>= 1;  
    }  
    return res;  
}  
  
inline void print_num(int x,int y,bool f){  
    if (!x){  
        if (f) printf("0");  
        return;  
    }  
    int w = 1;  
    if (x < 0){  
        x = -x;  
        w *= (-1);  
    }  
    if (y < 0){  
        y = -y;  
        w *= (-1);  
    }  
    int g = gcd(x,y);  
    x /= g;  
    y /= g;  
    if (!~w) printf("-");  
    if (y == 1) printf("%lld",x);  
    else printf("%lld/%lld",x,y);  
}  
  
inline pii get_sqrt(int x){  
    pii res = {1,1};  
    for (re int i = 2;i * i <= x;i++){  
        if (x % i == 0){  
            int cnt = 0;  
            while (x % i == 0){  
                cnt++;  
                x /= i;  
            }  
            res.fst *= qmi(i,cnt / 2);  
            res.snd *= max(1ll,i * (cnt % 2));  
        }  
    }  
    if (x != 1) res.snd *= x;  
    return res;  
}  
  
inline pii get_div(int w,bool ok,int x,int y){  
    if (x < 0){  
        x = -x;  
        w *= (-1);  
    }  
    if (y < 0){  
        y = -y;  
        w *= (-1);  
    }  
    int g = gcd(x,y);  
    x /= g;  
    y /= g;  
    if (ok){  
        if (~w) printf("+");  
        else printf("-");  
    }  
    return {x,y};  
}  
  
inline void solve(){  
    int w;  
    a = read();  
    b = read();  
    c = read();  
    int del = b * b - 4 * a * c;  
    if (del < 0){  
        puts("NO");  
        return;  
    }  
    if (!del){  
        print_num(-b,2 * a,true);  
        puts("");  
        return;  
    }  
    double sdel = sqrtl(del);  
    if ((1.0 * (-1.0 * b - sdel) / (2.0 * a)) > (1.0 * (-1.0 * b + sdel) / (2.0 * a))) w = -1;  
    else w = 1;  
    pii t = get_sqrt(del);  
    if (t.snd == 1){  
        int s = -b + w * t.fst;  
        int m = 2 * a;  
        print_num(s,m,true);  
    }  
    else{  
        double div = fabs((-b) / (2.0 * a));  
        bool ok;  
        print_num(-b,2 * a,false);  
        if (div > eps) ok = true;  
        else ok = false;  
        pii res = get_div(w,ok,t.fst,2 * a);  
        if (res.fst != 1) printf("%lld*",res.fst);  
        printf("sqrt(%lld)",t.snd);  
        if (res.snd != 1) printf("/%lld",res.snd);  
    }  
    puts("");  
}  
  
signed main(){  
    T = read();  
    lim = read();  
    while (T--) solve();  
    return 0;  
}  

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18268809

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(127)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示