[题解]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/BeautifulWish/p/P9750.html

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

posted @   BeautifulWish  阅读(210)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示