CSP-J 2023 T3 一元二次方程 解題報告

缪语博發表於2024-10-11

CSP-J 2023 T3 一元二次方程 解題報告

Link

前言

今年\(CSP\)的原題, 回家\(1h\)內寫\(AC\), 但是考場上沒有寫出來 , 原因是腦子太不好了, 竟然調了兩個小時沒有調出來. 一等獎懸那......

正題

看完題目,第一眼就是大模擬, 並且\(CCF\)絕對不會讓你好受,所以出了一個如此***鑽的題目, 並且要考慮到非常多的情況, 程式碼非常長......

最重要的一點: \(\Delta\)

\(\Delta\)是此題中最重要的分情況討論的地方. 根據初三\(22\)章的所學知識 ,可知分三種情況:

1. \(\Delta < 0\)

不用說了
直接輸出NO

2. \(\Delta = 0\)

同樣的, 只有一種情況, 答案為\(- \dfrac{b}{2a}\),但是, 需要嚴謹的判斷.

if(delta == 0) {
    if(b == 0) {
        cout << 0;
    }
    else if(a * b > 0) {
        a = abs(a);
        b = abs(b);
        cout << "-";
        if(b % (2 * a) == 0) {
            cout << b / 2 / a;
        }
        else {
            cout << b / __gcd(2 * a, b) << "/" << (2 * a) / __gcd(2 * a, b);
        }
    }
    else {
        a = abs(a);
        b = abs(b);
        if(b % (2 * a) == 0) {
            cout << b / 2 / a;
        }
        else {
            cout << b / __gcd(2 * a, b) << "/" << (2 * a) / __gcd(2 * a, b);
        }
    }
}

3. \(\Delta > 0\)

地獄.
我是分兩種情況的, 一種是\(a > 0\), 一種是\(a < 0\). 這樣可以分辨出是\(+ \sqrt{\Delta }\) 還是\(-\sqrt{\Delta }\)

如若\(a < 0\), 則可知答案為:

\[\dfrac{b + \sqrt{\Delta}}{-2a} \]

如若\(a > 0\), 則可知答案為:

\[\dfrac{\sqrt{\Delta} - b}{2a} \]

  • 在這裡有一個技巧, 就是不論怎樣, 輸出時, \(\sqrt{\Delta}\)永遠是正的(符號為+)

可以分兩種情況:
1.第一種: 不需要寫sqrt, 也就是\(\Delta\)完全平方數時,

比較好處理, 首先需要判斷\(b + \sqrt{\Delta}\)是否為\(0\). 如果是, 則直接輸出\(0\); 否則輸出最簡分數.

其中, 一定要記住如果\((b + \sqrt{\Delta}) \% (2 * a) = 0\), 就直接輸出一個整數.還要注意判斷正負號.

2.第二種: 需要寫sqrt, 很難.

首先, 先輸出前面的內容, 也就是\(-\dfrac{b}{2a}\), 判斷同上.

然後, 輸出+, 代表符號.

接著, 找出三個變數, 也就是: \(\dfrac{x}{y} \sqrt{\dfrac{\Delta}{x^2}}\)中的\(x, y和\dfrac{\Delta}{x^2}\).其中,\(\sqrt{\dfrac{\Delta}{x^2}}\)為最簡平方根數.

接下來是\(4\)種情況:

\(x = y\), 只有\(\sqrt{\dfrac{\Delta}{x^2}}\);

\(x \% y = 0\), 只有\(\dfrac{x}{y}\sqrt{\dfrac{\Delta}{x^2}}\)

\(y \% x = 0\), 只有\(\dfrac{\sqrt{\dfrac{\Delta}{x^2}}}{y}\)

其他情況, 輸出\(\dfrac{x \times \sqrt{\dfrac{\Delta}{x^2}}}{y}\)

完結撒花!!

\(Code:\)

  • 心臟病患者請勿觀看
#include <bits/stdc++.h>
using namespace std;

int T, M;
int a, b, c;

int pd(int x) {
    for(int i = sqrt(x) + 1; i >= 1; --i) {
        if(x % (i * i) == 0) {
            return i;
        }
    }
}

int main() {

    
    cin >> T >> M;

    while(T--) {
        cin >> a >> b >> c;
        
        int delta;

        delta = b * b - 4 * a * c;

        if(delta < 0) {
            cout << "NO";
        }
        else if(delta == 0) {
            if(b == 0) {
                cout << 0;
            }
            else if(a * b > 0) {
                a = abs(a);
                b = abs(b);
                cout << "-";
                if(b % (2 * a) == 0) {
                    cout << b / 2 / a;
                }
                else {
                    cout << b / __gcd(2 * a, b) << "/" << (2 * a) / __gcd(2 * a, b);
                }
            }
            else {
                a = abs(a);
                b = abs(b);
                if(b % (2 * a) == 0) {
                    cout << b / 2 / a;
                }
                else {
                    cout << b / __gcd(2 * a, b) << "/" << (2 * a) / __gcd(2 * a, b);
                }
            }
        }
        else {
            if(a < 0) {
                int mother = - 2 * a;
                int x = pd(delta);
                int y = delta / x / x;
                if(b == 0) {
                    mother = abs(mother);
                    if(y == 1) {
                        if(x == mother) {
                            cout << "1";
                        }
                        else if(x % mother == 0) {
                            cout << x / mother;
                        }
                        else {
                            cout << x / __gcd(x, mother) << "/" << mother / __gcd(x, mother);
                        }
                    }
                    else {
                        if(x == mother) {
                            cout << "sqrt(" << y << ")";
                        }
                        else if(mother % x == 0) {
                            cout << "sqrt(" << y << ")";
                            cout << "/" << mother / x;
                        }
                        else if(x % mother == 0) {
                            cout << x / mother << "*sqrt(" << y << ")";
                        }
                        else {
                            cout << x / __gcd(x, mother) << "*sqrt(" << y << ")" << "/" << mother / __gcd(x, mother);
                        }
                    }
                }
                else if(y == 1) { // 不需要sqrt
                    // 說明可以合併為同一個式子
                    int son = - b - x;
                    if(son == 0) {
                        cout << 0;
                    }
                    else if(son * mother < 0) { // 如果分子分母同號.
                        son = abs(son);
                        mother = abs(mother);
                        if(son % mother == 0) {
                            cout << son / mother;
                        }
                        else {
                            cout << son / __gcd(son, mother) << "/" << mother / __gcd(son, mother);
                        }
                    }
                    else { // 如果分子分母異號.
                        son = abs(son);
                        mother = abs(mother);
                        cout << "-";
                        if(son % mother == 0) {
                            cout << son / mother;
                        }
                        else {
                            cout << son / __gcd(son, mother) << "/" << mother / __gcd(son, mother);
                        }
                    }
                }
                else { // 需要sqrt.
                    // 1. 先輸出前面的
                    if(b > 0) { // 不需要負號
                        b = abs(b);
                        mother = abs(mother);
                        if(b % mother == 0) {
                            cout << b / mother;
                        }
                        else {
                            cout << b / __gcd(b, mother) << "/" << mother / __gcd(b, mother);
                        }
                    }
                    else { // 需要負號
                        b = abs(b);
                        mother = abs(mother);
                        cout << "-";
                        if(b % mother == 0) {
                            cout << b / mother;
                        }
                        else {
                            cout << b / __gcd(b, mother) << "/" << mother / __gcd(b, mother);
                        }
                    }
                    // 2. 輸出sqrt部分(不管怎樣都是+)
                    cout << "+";
                    if(x == 1) { // 不需要輸出字首.
                        cout << "sqrt(" << y << ")";
                        cout << "/" << - 2 * a;
                    }
                    else {
                        if(x == mother) {
                            cout << "sqrt(" << y << ")";
                        }
                        else if(x % mother == 0) {
                            cout << x / mother << "*sqrt(" << y << ")";
                        }
                        else if(mother % x == 0) {
                            cout << "sqrt(" << y << ")";
                            cout << "/" << mother / x;
                        }
                        else {
                            cout << x / __gcd(x, mother);
                            cout << "*sqrt(" << y << ")";
                            cout << "/" << mother / __gcd(x, mother);
                        }
                    }
                }
            }
            else {
                int mother = 2 * a;
                int x = pd(delta);
                int y = delta / x / x;
                if(b == 0) {
                    mother = abs(mother);
                    if(y == 1) {
                        if(x == mother) {
                            cout << "1";
                        }
                        else if(x % mother == 0) {
                            cout << x / mother;
                        }
                        else {
                            cout << x / __gcd(x, mother) << "/" << mother / __gcd(x, mother);
                        }
                    }
                    else {
                        if(x == mother) {
                            cout << "sqrt(" << y << ")";
                        }
                        else if(mother % x == 0) {
                            cout << "sqrt(" << y << ")";
                            cout << "/" << mother / x;
                        }
                        else if(x % mother == 0) {
                            cout << x / mother << "*sqrt(" << y << ")";
                        }
                        else {
                            cout << x / __gcd(x, mother) << "*sqrt(" << y << ")" << "/" << mother / __gcd(x, mother);
                        }
                    }
                }
                else if(y == 1) { // 不需要sqrt
                    // 說明可以合併為同一個式子
                    int son = - b + x;
                    if(son == 0) {
                        cout << 0;
                    }
                    else if(son * mother > 0) { // 如果分子分母同號.
                        son = abs(son);
                        mother = abs(mother);
                        if(son % mother == 0) {
                            cout << son / mother;
                        }
                        else {
                            cout << son / __gcd(son, mother) << "/" << mother / __gcd(son, mother);
                        }
                    }
                    else { // 如果分子分母異號.
                        son = abs(son);
                        mother = abs(mother);
                        cout << "-";
                        if(son % mother == 0) {
                            cout << son / mother;
                        }
                        else {
                            cout << son / __gcd(son, mother) << "/" << mother / __gcd(son, mother);
                        }
                    }
                }
                else { // 需要sqrt.
                    // 1. 先輸出前面的
                    if(b * mother < 0) { // 不需要負號
                        b = abs(b);
                        mother = abs(mother);
                        if(b % mother == 0) {
                            cout << b / mother;
                        }
                        else {
                            cout << b / __gcd(b, mother) << "/" << mother / __gcd(b, mother);
                        }
                    }
                    else { // 需要負號
                        b = abs(b);
                        mother = abs(mother);
                        cout << "-";
                        if(b % mother == 0) {
                            cout << b / mother;
                        }
                        else {
                            cout << b / __gcd(b, mother) << "/" << mother / __gcd(b, mother);
                        }
                    }
                    // 2. 輸出sqrt部分(不管怎樣都是+)
                    cout << "+";
                    if(x == 1) { // 不需要輸出字首.
                        cout << "sqrt(" << y << ")";
                        cout << "/" << 2 * a;
                    }
                    else {
                        mother = 2 * a;
                        if(x == mother) {
                            cout << "sqrt(" << y << ")";
                        }
                        else if(x % mother == 0) {
                            cout << x / mother << "*sqrt(" << y << ")";
                        }
                        else if(mother % x == 0) {
                            cout << "sqrt(" << y << ")";
                            cout << "/" << mother / x;
                        }
                        else {
                            cout << x / __gcd(x, mother);
                            cout << "*sqrt(" << y << ")";
                            cout << "/" << mother / __gcd(x, mother);
                        }
                    }
                }
            }
        }
        cout << endl;
    }

    return 0;
}

相關文章