#include<bits/stdc++.h>
using namespace std;
int t,m;
void yf(int &x,int &y)//约分x/y
{
bool bs=0;
if(x==0)
{
return;
}
if((x<0)^(y<0)==1)//结果为负
{
if(x<0)x=-x;
if(y<0)y=-y;
bs=1;
}
int g=__gcd(x,y);
x/=g;
y/=g;
if(bs==1)x=-x;
}
int gen(int x)
{
for(int i=(int)(sqrt(x))+1;i>=1;i--)
{
if(x%(i*i)==0)return i;
}
return 1;
}
int main()
{
//freopen("uqe.in","r",stdin);
//freopen("uqe.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t>>m;
while(t--)
{
int a,b,c,dt=0;
cin>>a>>b>>c;
dt=b*b-4*a*c;
//cout<<dt<<" "<<(int)(sqrt(dt))*(int)(sqrt(dt))<<" ";
if(dt<0)
{
cout<<"NO\n";
continue;
}
else if((int)(sqrt(dt))*(int)(sqrt(dt))==dt)//存在有理数根
{
if(c==0)
{
yf(b,a);
if(-b*1.0/a>0)//-b/a更大
{
if(a==1)cout<<-b<<"\n";
else cout<<-b<<"/"<<a<<"\n";
}
else cout<<0<<"\n";
}
else
{
int ans1=0,ans2=0;
ans1=(-b+sqrt(dt))*1.0/(2*a);
ans2=(-b-sqrt(dt))*1.0/(2*a);
//cout<<ans1<<" "<<ans2<<"\n";
if(a*ans1*ans1+b*ans1+c==0&&a*ans2*ans2+b*ans2+c==0)//解为整数
{
cout<<max(ans1,ans2)<<"\n";
}
else
{
int dba=2*a,sqd=(int)(sqrt(dt)),fz;//fz为答案的分子
//cout<<b<<" "<<sqd<<" "<<dba<<"\n";
if(a>0)//选正根
{
fz=-b+sqd;
}
else //选负根
{
fz=-b-sqd;
}
yf(fz,dba);
if(dba==1)cout<<fz<<"\n";
else cout<<fz<<"/"<<dba<<"\n";
}
}
}
else
{
bool flg=0;
int dba=2*a;
yf(b,dba);
if(b!=0)
{
if(dba==1)cout<<-b;
else cout<<-b<<"/"<<dba;
}
else flg=1;//在根号之前,没有输出任何东西
int p;
p=gen(dt);
dt=dt/(p*p);
dba=2*a;
yf(p,dba);
if(flg==0)cout<<"+";
if(p<0)p=-p;
if(p==1)
{
if(dba==1)cout<<"sqrt("<<dt<<")\n";
else cout<<"sqrt("<<dt<<")/"<<dba<<"\n";
}
else
{
if(dba==1)cout<<p<<"*sqrt("<<dt<<")\n";
else cout<<p<<"*sqrt("<<dt<<")/"<<dba<<"\n";
}
}
}
return 0;
}
码风有点丑,望理解。
如果想兼容性质C部分分,方程验算时,一定不要直接代回原方程,因为有可能实际上一个解是整数,另一个不是,但实数丢失精度后使得两根相等,可能就会输出小的那个整数根。
hack:
1 10
2 -5 3
expected:3/2