社区讨论

求hack,讨论区里的所有hack都没hack我

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

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@lojtft3y
此快照首次捕获于
2023/11/04 17:02
2 年前
此快照最后确认于
2023/11/04 19:31
2 年前
查看原帖
CPP
/*
最大的根不一定是q1+q2,若a<0,则最大根是q1-q2 
*/

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

int m,a,b,c;
long long num[10005];
bool vis[10000005];

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

int apart(int dirta)
{
	int d=dirta;
	for(int i=2;i<=1000;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不是整数 
	{
		int gcd=__gcd(abs(2*a),abs(b));
		if(q1>0)       //q1前没有符号 
		{
			printf("%d/%d",abs(b)/gcd,abs(2*a)/gcd);
		}
		else if(q1<0)       //q1前有符号 
		{
			printf("-%d/%d",abs(b)/gcd,abs(2*a)/gcd);
		}
	}
}

void solveq2(int 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("+");
		
		int d=apart(dirta),p=sqrt(dirta/d);  //d是根号里的数,p是根号的倍数
		int 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("-%d*sqrt(%d)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("-sqrt(%d)\n",d);
				}
				else
				{
					if(p/gcd!=1)printf("%d*sqrt(%d)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("sqrt(%d)\n",d);
				}
			}
			
			else    //q2=+p*sqrt(d)/2a 
			{
				if(p/2.0/a>0)
				{
					if(p/gcd!=1)printf("%d*sqrt(%d)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("sqrt(%d)\n",d);
				}
				else
				{
					if(p/gcd!=1)printf("-%d*sqrt(%d)\n",abs(p)/gcd,d);     //判断p是否为1 
					else printf("-sqrt(%d)\n",d);
				}
			}
		}
		
		else      //不是整数,有分数形式 
		{
			if(a<0)      //q2=-p*sqrt(d)/2a
			{
				if(p/2.0/a>0)
				{
					if(p/gcd!=1)printf("-%d*sqrt(%d)/%d\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("-sqrt(%d)/%d\n",d,abs(2*a)/gcd);
				}
				else
				{
					if(p/gcd!=1)printf("%d*sqrt(%d)/%d\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("sqrt(%d)/%d\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("%d*sqrt(%d)/%d\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("sqrt(%d)/%d\n",d,abs(2*a)/gcd);
				}
				else
				{
					if(p/gcd!=1)printf("-%d*sqrt(%d)/%d\n",abs(p)/gcd,d,abs(2*a)/gcd);     //判断p是否为1 
					else printf("-sqrt(%d)/%d\n",d,abs(2*a)/gcd);
				}
			}
		}
	}
}

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

int main()
{
	int t;
	scanf("%d%d",&t,&m);
	for(int i=1;i<=1000;i++)
	{
		vis[i*i]=1;
		num[i]=i*i;
	}
	while(t--)
	{
		scanf("%d%d%d",&a,&b,&c);
		
		int 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;
} 

回复

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

正在加载回复...