警示后人,一种不下数据几乎不可能调得出的错误
查看原帖
警示后人,一种不下数据几乎不可能调得出的错误
530797
code_hyx楼主2024/8/29 21:53
#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
2024/8/29 21:53
加载中...