[题解]P9750 [CSP-J 2023] 一元二次方程
思路
大模拟,按照题意模拟即可。
首先按照 的取值分为 类:
-
。
-
。
-
。
对于第 1 种情况,根据题意,输出 NO
。
对于第 2 种情况,原方程只会有一个解为 ,求一个 约分即可。
对于第 3 种情况,原方程会有两个解 ,此时我们可以得到此时取 更优,还是取 更优。在这里我们定义 表示在原方程中取 / 更优。
然后化简 为一个 pair t
,表示 并且满足 最简。
将 的取值也分为 种情况:
-
。
-
。
对于第 1 种情况,答案为 。
对于第 2 种情况,由于 有可能为 ,所以需要单独判断一下即可。
Code
#include <bits/stdc++.h>
#define fst first
#define snd second
#define re register
#define int long long
#define double long double
using namespace std;
typedef pair<int,int> pii;
const double eps = 1e-5;
int T,lim,a,b,c;
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 1) + (r << 3) + (c ^ 48);
c = getchar();
}
return r * w;
}
inline int gcd(int a,int b){
if (!b) return a;
return gcd(b,a % b);
}
inline int qmi(int a,int b){
int res = 1;
while (b){
if (b & 1) res *= a;
a *= a;
b >>= 1;
}
return res;
}
inline void print_num(int x,int y,bool f){
if (!x){
if (f) printf("0");
return;
}
int w = 1;
if (x < 0){
x = -x;
w *= (-1);
}
if (y < 0){
y = -y;
w *= (-1);
}
int g = gcd(x,y);
x /= g;
y /= g;
if (!~w) printf("-");
if (y == 1) printf("%lld",x);
else printf("%lld/%lld",x,y);
}
inline pii get_sqrt(int x){
pii res = {1,1};
for (re int i = 2;i * i <= x;i++){
if (x % i == 0){
int cnt = 0;
while (x % i == 0){
cnt++;
x /= i;
}
res.fst *= qmi(i,cnt / 2);
res.snd *= max(1ll,i * (cnt % 2));
}
}
if (x != 1) res.snd *= x;
return res;
}
inline pii get_div(int w,bool ok,int x,int y){
if (x < 0){
x = -x;
w *= (-1);
}
if (y < 0){
y = -y;
w *= (-1);
}
int g = gcd(x,y);
x /= g;
y /= g;
if (ok){
if (~w) printf("+");
else printf("-");
}
return {x,y};
}
inline void solve(){
int w;
a = read();
b = read();
c = read();
int del = b * b - 4 * a * c;
if (del < 0){
puts("NO");
return;
}
if (!del){
print_num(-b,2 * a,true);
puts("");
return;
}
double sdel = sqrtl(del);
if ((1.0 * (-1.0 * b - sdel) / (2.0 * a)) > (1.0 * (-1.0 * b + sdel) / (2.0 * a))) w = -1;
else w = 1;
pii t = get_sqrt(del);
if (t.snd == 1){
int s = -b + w * t.fst;
int m = 2 * a;
print_num(s,m,true);
}
else{
double div = fabs((-b) / (2.0 * a));
bool ok;
print_num(-b,2 * a,false);
if (div > eps) ok = true;
else ok = false;
pii res = get_div(w,ok,t.fst,2 * a);
if (res.fst != 1) printf("%lld*",res.fst);
printf("sqrt(%lld)",t.snd);
if (res.snd != 1) printf("/%lld",res.snd);
}
puts("");
}
signed main(){
T = read();
lim = read();
while (T--) solve();
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18268809
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效