4472: 一元二次方程 [CSP-J 2023]

内存限制:512 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:1 解决:1

题目描述

样例输入 复制

9 1000
1 -1 0
-1 -1 -1
1 -2 1
1 5 4
4 4 1
1 0 -432
1 -3 1
2 -4 1
1 7 1

样例输出 复制

1
NO
1
-1
-1/2
12*sqrt(3)
3/2+sqrt(5)/2
1+sqrt(2)/2
-7/2+3*sqrt(5)/2

提示

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

int t, m;
//最大公约数,约分时候使用
int gcd(int a, int b) {
  return b == 0 ? a : gcd(b, a % b);
}

int main() {
  cin >> t >> m;
  while (t--) {
    int a, b, c;  cin >> a >> b >> c;
    int delta = b * b - 4 * a * c;
    //若delta<0,方程无实数解,输出NO
    if (delta < 0) {
      cout << "NO" << endl;
      continue;
    }
    //delta>=0,方程有两个解分别为x1,x2,a的符号不同,则两者中较大的不同
    //x的通用表示为x=p/q+sqr_del/q
    int sqr_del = 1;
    //求根号delta->sqr_del
    for (int i = 2; i * i <= delta; i++) {
      while (delta % (i * i) == 0)
        sqr_del *= i, delta /= i * i;
    }
    int p = -b, q = 2 * a;
    if (q < 0) q = -q, p = -p;
    //如果sqr_del是整数,那么p需要加上sqr_del
    if (delta == 1) delta = 0, p += sqr_del;
    //x=p/q+sqr_del/q,考虑约分,需要分别求p,q和sqr_del,q的最大公约数g1,g2
    int g1 = gcd(abs(p), q), g2 = gcd(sqr_del, q);
    //如果sqr_del是整数那么答案为p/q
    if (delta == 0) {
      if (p % q == 0) cout << p / q;
      else cout << p / g1 << "/" << q / g1;//约分
    }
    //如果sqr_del不是整数,则需要分别处理p/q和sqr_del/q
    else {
      if (p != 0) {
        if (p % q == 0) cout << p / q;
        else cout << p / g1 << "/" << q / g1;//约分
        cout << "+";
      }
      
      if (sqr_del / g2 != 1) cout << sqr_del / g2 << "*";
      cout << "sqrt(" << delta << ")";
      if (q / g2 != 1) cout << "/" << q / g2;
    
    }
    cout << endl;
  }
  return 0;
}