社区讨论

70pts求助

P9750[CSP-J 2023] 一元二次方程参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lokt03em
此快照首次捕获于
2023/11/05 09:37
2 年前
此快照最后确认于
2023/11/05 11:05
2 年前
查看原帖
拍子挂了一个晚上,还是没查出错
哪个好心人帮我拍一下
CPP
/*
最大的根不一定是q1+q2,若a<0,则最大根是q1-q2 
*/

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

long long m,a,b,c;
long long num[3005];
bool vis[3005*3005];

bool is_zs(double x)   //判断是否为整数 
{
	if(x==int(x))return 1;
	return 0;
}

long long apart(long long dirta)
{
	long long d=dirta;
	for(long long i=2;i<=3000;i++)
	{
		if(d==1)return d;
		while(d%num[i]==0)d/=num[i];
	}
	return d;  //返回的是根号里的数 
}

void solveq1()
{
	double q1=-b/2.0/a;
	if(is_zs(q1) && q1!=0)     //q1为整数
	{
		printf("%d",int(q1));
	}
	
	else   //q1不是整数 
	{
		long long gcd=__gcd(abs(2*a),abs(b));
		if(q1>0)       //q1前没有符号 
		{
			printf("%lld/%lld",abs(b)/gcd,abs(2*a)/gcd);
		}
		else if(q1<0)       //q1前有符号 
		{
			printf("-%lld/%lld",abs(b)/gcd,abs(2*a)/gcd);
		}
	}
}

void solveq2(long long dirta)
{
	double q1=-b/2.0/a;
	
	if(dirta==0)
	{
		if(q1==0)printf("0"); 
		printf("\n");
	}
	else if(dirta!=0)
	{
		if(q1!=0)printf("+");
		
		long long d=apart(dirta),p=sqrt(dirta/d);  //d是根号里的数,p是根号的倍数
		long long gcd=__gcd(abs(p),abs(2*a));
		//已经判断过符号,不再判断
		
		if(is_zs(p/2.0/a))  //判断整数
		{
			if(a<0)    //q2=-p*sqrt(d)/2a 
			{
				if(p/2.0/a>0)
				{
					if(p/gcd!=1)printf("-%lld*sqrt(%lld)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("-sqrt(%lld)\n",d);
				}
				else
				{
					if(p/gcd!=1)printf("%lld*sqrt(%lld)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("sqrt(%lld)\n",d);
				}
			}
			
			else    //q2=+p*sqrt(d)/2a 
			{
				if(p/2.0/a>0)
				{
					if(p/gcd!=1)printf("%lld*sqrt(%lld)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("sqrt(%lld)\n",d);
				}
				else
				{
					if(p/gcd!=1)printf("-%lld*sqrt(%lld)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("-sqrt(%lld)\n",d);
				}
			}
		}
		
		else      //不是整数,有分数形式 
		{
			if(a<0)      //q2=-p*sqrt(d)/2a
			{
				if(p/2.0/a>0)
				{
					if(p/gcd!=1)printf("-%lld*sqrt(%lld)/%lld\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("-sqrt(%lld)/%lld\n",d,abs(2*a)/gcd);
				}
				else
				{
					if(p/gcd!=1)printf("%lld*sqrt(%lld)/%lld\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("sqrt(%lld)/%lld\n",d,abs(2*a)/gcd);
				}
			}
			
			if(a>0)      //q2=+p*sqrt(d)/2a
			{
				if(p/2.0/a>0)
				{
					if(p/gcd!=1)printf("%lld*sqrt(%lld)/%lld\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("sqrt(%lld)/%lld\n",d,abs(2*a)/gcd);
				}
				else
				{
					if(p/gcd!=1)printf("-%lld*sqrt(%lld)/%lld\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("-sqrt(%lld)/%lld\n",d,abs(2*a)/gcd);
				}
			}
		}
	}
}

void special(long long dirta)
{
	if(a>0)
	{
		long long p=-b+sqrt(dirta),q=2*a;
		if(is_zs(p/1.0/q))            //根是整数
		{
			printf("%lld\n",p/q);
		}
		else
		{
			long long gcd=__gcd(abs(p),abs(q));
			if(p/q>=0)printf("%lld/%lld\n",abs(p)/gcd,abs(q)/gcd);    //正数根 
			else printf("-%lld/%lld\n",abs(p)/gcd,abs(q)/gcd);    //负数根 
		}
	}
	
	else
	{
		long long p=-b-sqrt(dirta),q=2*a;
		if(is_zs(p/1.0/q))            //根是整数
		{
			printf("%lld\n",p/q);
		}
		else
		{
			long long gcd=__gcd(abs(p),abs(q));
			if(p/q>=0)printf("%lld/%lld\n",abs(p)/gcd,abs(q)/gcd);    //正数根 
			else printf("-%lld/%lld\n",abs(p)/gcd,abs(q)/gcd);    //负数根 
		}
	}
}

int main()
{
//	freopen("uqe.in","r",stdin);
//	freopen("uqe.ans","w",stdout);
	
	long long t;
	scanf("%lld%lld",&t,&m);
	for(long long i=1;i<=3000;i++)
	{
		vis[i*i]=1;
		num[i]=i*i;
	}
	while(t--)
	{
		scanf("%lld%lld%lld",&a,&b,&c);
		
		long long dirta=b*b-4*a*c;
		if(dirta<0)         //无解 
		{
			printf("NO\n");
			continue;
		}
		
		else if(vis[dirta])   //dirta是平方数,特判
		{
			special(dirta);
		}
		
		else              //有解 
		{
			solveq1();
			solveq2(dirta);
		}
	}
	
	return 0;
} 

回复

0 条回复,欢迎继续交流。

正在加载回复...