CSP历年复赛题-P9750 [CSP-J 2023] 一元二次方程

原题链接:https://www.luogu.com.cn/problem/P9750

题意解读:根据公式,输出结果。

解题思路:本题是一道较为繁琐的模拟题,分情况讨论即可,需要细心。

先计算deta = b * b - 4 * a * c

1、deta < 0则无根,输出NO

2、如果有根,较大的根是:-b/2a+sqrt(deta)/2abs(a)

3、判断deta是否是完全平方数

  3.1 deta是完全平方数,说明根是有理数,直接计算x=sqrt(deta),然后分a正负将-b/2a+x/2abs(a)的符号、分子、分母分别计算出来

 //较大的根为-b/2a+sqrt(deta)/2abs(a)
        int x = sqrt(deta);
        if(x * x == deta) //如果根是有理数,也就是deta是完全平方数,直接计算根的分子、分母
        {
            int s, c, d; //符号,分子,分母
            if(a > 0) c = sqrt(deta) - b, d = 2 * a;
            if(a < 0) c = sqrt(deta) + b, d = 2 * abs(a);
            if(c < 0) s = -1;
            else s = 1;
            c = abs(c), d = abs(d);
            int g = gcd(c, d);
            c /= g, d /= g;
            if(c == 0) cout << 0; //注意如果根是0,要输出0
            if(c != 0)
            {
                if(s < 0) cout << "-";
                cout << c;
                if(d > 1) cout << "/" << d;
            }
        }

  3.2 deta不是完全平方数

    3.2.1 先计算q1

            //q1=-b/2a
            if(b != 0) //b=0则不用输出q1
            {
                int s = -1; //q1的符号
                if(a * b < 0) s *= -1; //计算q1的符号
                if(s < 0) cout << "-"; //输出符号
                int c = abs(b), d = abs(2 * a); //q1的分子分母
                int g = gcd(c, d);
                c /= g, d /= g;
                cout << c;
                if(d > 1) cout << "/" << d;
            }

    3.2.2 再将sqrt(deta)分解为x*sqrt(r),也就是消除deta中的完全平方因子

//sqrt(deta) = x*sqrt(r)
            //根的后半部分为x*sqrt(r)/2abs(a)
            int x = 1;
            for(int i = sqrt(deta); i >= 1; i--)
            {
                if(deta % (i * i) == 0) 
                {
                    x = i; //找到deta里最大的完全平方因子
                    break;
                }
            }
            int r = deta / (x * x);

    3.2.3 最后计算q2

            //q2=x/2abs(a)
            int c = x, d = 2 * abs(a); //q2的分子,分母
            int g = gcd(c, d);
            c /= g, d /= g;

            if(b != 0) cout << "+";
            if(c == 1 && d == 1) cout << "sqrt(" << r << ")";
            if(c != 1 && d == 1) cout << c << "*sqrt(" << r << ")";
            if(c == 1 && d != 1) cout << "sqrt(" << r << ")/" << d;
            if(c != 1 && d != 1) cout << c << "*sqrt(" << r << ")/" << d;

100分代码:

#include <bits/stdc++.h>
using namespace std;

int t, m, a, b, c;

int gcd(int a, int b)
{
    if(b == 0) return a;
    return gcd(b, a % b);
}

int main()
{
    cin >> t >> m;
    while(t--)
    {
        cin >> a >> b >> c;
        int deta = b * b - 4 * a * c;
        if(deta < 0)
        {
            cout << "NO" << endl;
            continue;
        }
        //较大的根为-b/2a+sqrt(deta)/2abs(a)
        int x = sqrt(deta);
        if(x * x == deta) //如果根是有理数,也就是deta是完全平方数,直接计算根的分子、分母
        {
            int s, c, d; //符号,分子,分母
            if(a > 0) c = sqrt(deta) - b, d = 2 * a;
            if(a < 0) c = sqrt(deta) + b, d = 2 * abs(a);
            if(c < 0) s = -1;
            else s = 1;
            c = abs(c), d = abs(d);
            int g = gcd(c, d);
            c /= g, d /= g;
            if(c == 0) cout << 0; //注意如果根是0,要输出0
            if(c != 0)
            {
                if(s < 0) cout << "-";
                cout << c;
                if(d > 1) cout << "/" << d;
            }
        }
        else
        {
            //q1=-b/2a
            if(b != 0) //b=0则不用输出q1
            {
                int s = -1; //q1的符号
                if(a * b < 0) s *= -1; //计算q1的符号
                if(s < 0) cout << "-"; //输出符号
                int c = abs(b), d = abs(2 * a); //q1的分子分母
                int g = gcd(c, d);
                c /= g, d /= g;
                cout << c;
                if(d > 1) cout << "/" << d;
            }
            //sqrt(deta) = xsqrt(r)
            //根的后半部分为xsqrt(r)/2abs(a)
            //q2=x/2abs(a)
            int x = 1;
            for(int i = sqrt(deta); i >= 1; i--)
            {
                if(deta % (i * i) == 0) 
                {
                    x = i; //找到deta里最大的完全平方因子
                    break;
                }
            }
            int r = deta / (x * x);
            int c = x, d = 2 * abs(a); //q2的分子,分母
            int g = gcd(c, d);
            c /= g, d /= g;

            if(b != 0) cout << "+";
            if(c == 1 && d == 1) cout << "sqrt(" << r << ")";
            if(c != 1 && d == 1) cout << c << "*sqrt(" << r << ")";
            if(c == 1 && d != 1) cout << "sqrt(" << r << ")/" << d;
            if(c != 1 && d != 1) cout << c << "*sqrt(" << r << ")/" << d;
            
        }    
        cout << endl;
        
    }
    return 0;
}

 

posted @ 2024-06-20 17:08  五月江城  阅读(302)  评论(0编辑  收藏  举报