CSP-J 2023 T3 一元二次方程 解题报告

CSP-J 2023 T3 一元二次方程 解题报告

Link

前言

今年 C S P CSP CSP的原题, 回家 1 h 1h 1h内写 A C AC AC, 但是考场上没有写出来 , 原因是脑子太不好了, 竟然调了两个小时没有调出来. 一等奖悬那...

正题

看完题目,第一眼就是大模拟, 并且 C C F CCF CCF绝对不会让你好受,所以出了一个如此刁钻的题目, 并且要考虑到非常多的情况, 代码非常长...

最重要的一点: Δ \Delta Δ

Δ \Delta Δ是此题中最重要的分情况讨论的地方. 根据初三 22 22 22章的所学知识 ,可知分三种情况:

1. Δ < 0 \Delta < 0 Δ<0

不用说了

直接输出NO

2. Δ = 0 \Delta = 0 Δ=0

同样的, 只有一种情况, 答案为 − b 2 a - \dfrac{b}{2a} −2ab,但是, 需要严谨的判断.

cpp 复制代码
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. Δ > 0 \Delta > 0 Δ>0

地狱.

我是分两种情况的, 一种是 a > 0 a > 0 a>0, 一种是 a < 0 a < 0 a<0. 这样可以分辨出是 + Δ + \sqrt{\Delta } +Δ 还是 − Δ -\sqrt{\Delta } −Δ

如若 a < 0 a < 0 a<0, 则可知答案为:
b + Δ − 2 a \dfrac{b + \sqrt{\Delta}}{-2a} −2ab+Δ

如若 a > 0 a > 0 a>0, 则可知答案为:
Δ − b 2 a \dfrac{\sqrt{\Delta} - b}{2a} 2aΔ −b

  • 在这里有一个技巧, 就是不论怎样, 输出时, Δ \sqrt{\Delta} Δ 永远是正的(符号为+)

可以分两种情况:

1.第一种: 不需要写sqrt, 也就是 Δ \Delta Δ为完全平方数时,

比较好处理, 首先需要判断 b + Δ b + \sqrt{\Delta} b+Δ 是否为 0 0 0. 如果是, 则直接输出 0 0 0; 否则输出最简分数.

其中, 一定要记住如果 ( b + Δ ) % ( 2 ∗ a ) = 0 (b + \sqrt{\Delta}) \% (2 * a) = 0 (b+Δ )%(2∗a)=0, 就直接输出一个整数.还要注意判断正负号.

2.第二种: 需要写sqrt, 很难.

首先, 先输出前面的内容, 也就是 − b 2 a -\dfrac{b}{2a} −2ab, 判断同上.

然后, 输出+, 代表符号.

接着, 找出三个变量, 也就是: x y Δ x 2 \dfrac{x}{y} \sqrt{\dfrac{\Delta}{x^2}} yxx2Δ 中的 x , y 和 Δ x 2 x, y和\dfrac{\Delta}{x^2} x,y和x2Δ.其中, Δ x 2 \sqrt{\dfrac{\Delta}{x^2}} x2Δ 为最简平方根数.

接下来是 4 4 4种情况:

x = y x = y x=y, 只有 Δ x 2 \sqrt{\dfrac{\Delta}{x^2}} x2Δ ;

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

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

其他情况, 输出 x × Δ x 2 y \dfrac{x \times \sqrt{\dfrac{\Delta}{x^2}}}{y} yx×x2Δ

完结撒花!!

C o d e : Code: Code:

  • 心脏病患者请勿观看
cpp 复制代码
#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;
}
相关推荐
lxyzcm26 分钟前
深入理解C++23的Deducing this特性(上):基础概念与语法详解
开发语言·c++·spring boot·设计模式·c++23
Schwertlilien34 分钟前
图像处理-Ch1-数字图像基础
图像处理·人工智能·算法
程序员一诺35 分钟前
【深度学习】嘿马深度学习笔记第10篇:卷积神经网络,学习目标【附代码文档】
人工智能·python·深度学习·算法
过过过呀Glik1 小时前
在 Ubuntu 上安装 Muduo 网络库的详细指南
linux·c++·ubuntu·boost·muduo
刚学HTML2 小时前
leetcode 05 回文字符串
算法·leetcode
蜀黍@猿2 小时前
【C++ 基础】从C到C++有哪些变化
c++
Am心若依旧4092 小时前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
zh路西法2 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
AC使者2 小时前
#B1630. 数字走向4
算法
冠位观测者3 小时前
【Leetcode 每日一题】2545. 根据第 K 场考试的分数排序
数据结构·算法·leetcode