一元二次方程

这时一个周五的清晨,本蒟蒻 生病了,居家观察。我闲的没事干,就开始调一道大模拟啦: P9750 [CSP-J 2023] 一元二次方程(何人有这等操作?!)。

历经了 1.5ℎ1.5h 的辛苦调试,我以 6262 行的代码AC了。

这次经历使我难忘,特写此篇,已做记录!

题解

本道题目的重难点就是 输出表达式 了!

本蒟蒻 十分粗心,于是我只能用函数解决了(哪位大佬有不用函数的请留言一下)。

函数如下:

check(int x) 函数:

这个函数很简单,只需要求出 \sqrt{x},非完全平方数返回-1。

代码:

int check(int x){
    for (int i=0; i*i<=x; i++){
        if (i*i==x) return i;
    }
    return -1;
}

solve_fs(int x,int y) 函数:

这个也不难,就是给你 x,y,求出 \frac{x}{y} 的最简形式(以pair给出),并且 y>0 。

我们可以先求出 gcd(x,y) ,然后令 x,y 除以他。

代码:

pr solve_fs(int x,int y){
	int g=__gcd(x,y);
	x/=g; y/=g;
	if (y<0){
		x=-x; y=-y;
	}
	return make_pair(x,y);
}

solve_yls(int x) 函数: 

归入正题,解决有理数。这里的x表示小三角。

我们可以先存储一下 s,s 的值是 check(x)。

接下来我们就获取到一个分数 max(\frac{-b+s}{2a},\frac{-b-s}{2a})。可以发现,如果 a 的值为正,则第一个分数大,否则第二个大。

接下来就是调用函数了!注意若分母为一,则只输出分子。

代码:

void solve_yls(int x){
	int sqr=check(x);
	int tmp=((2*a)>=0?(-b+sqr):(-b-sqr));
	pr ans=solve_fs(tmp,2*a);
	cout<<ans.first;
	if (ans.second!=1) cout<<"/"<<ans.second;
}

solve_sqrt(int x) 函数: 

十分重要,输出 \frac{\sqrt{x}}{2a},依据格式,我们还是先求出最大的 s,s^2|x

我们先按照前面的输出 \frac{s}{2a} 最简形式分子,然后输出乘以 sqrt{x\div s^2} ,最后输出除以分母。

注意乘除 1 可以省略。

代码:

void solve_sqrt(int x){
	int sqr=0;
	for (int i=1; i*i<=x; i++){
		if (x%(i*i)==0) sqr=i;
	}x/=(sqr*sqr);
	pr ans=solve_fs(sqr,2*a);
	if (ans.first!=1)cout<<ans.first<<"*";
	cout<<"sqrt("<<x<<")";
	if (ans.second!=1) cout<<"/"<<ans.second;
}

solve_wls(int x) 和 main() 函数:

无理数就轻而易举了吧,先输出 \frac{-b}{2a},然后调用 solve_sqrt。

注意 \frac{-b}{2a}=0 的情况不用输出,代码:

void solve_wls(int x){
	pr ans=solve_fs(-b,2*a);
	if (ans.first!=0){
		cout<<ans.first;
		if (ans.second!=1) cout<<"/"<<ans.second;
		cout<<"+";
	}
	if (a<0) a=-a;
	solve_sqrt(x);
}

而 main() 的任务就是计算小三角,很简单:

int main(){
	cin>>n>>m;
	while (n--){
		cin>>a>>b>>c;
		int x=b*b-4*a*c;
		if (x<0) cout<<"NO";
		else{
			if (check(x)!=-1){
				solve_yls(x);
			}
			else{
				solve_wls(x);
			}
		}
		cout<<"\n";
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值