CSP歷年複賽題-P9750 [CSP-J 2023] 一元二次方程

五月江城發表於2024-06-20

原題連結: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.3 先計算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.4 再將sqrt(deta)分解為xsqrt(r),也就是消除deta中的完全平方因子

            //sqrt(deta) = xsqrt(r)
            //根的後半部分為xsqrt(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.5 最後計算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;
}

相關文章