社区讨论

题解思路

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

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@m203532l
此快照首次捕获于
2024/10/08 14:54
去年
此快照最后确认于
2024/10/08 15:17
去年
查看原帖
这是一道难度比较高的大模拟,需要读懂题目的同时学习解一元二次方程。
首先如果会解一元二次方程或读懂了题目的人,都会先把Δ求出。 而通过题目可以知道: Δ=b24acΔ=b²-4ac。 而题目的要求是,“如果Δ<0则无解”,所以要进行判断
CPP
d = b * b - 4 * a * c;
if(d < 0) cout << "NO";
输出NO的情况就搞定了。
次要是使用韦达定理解一元二次方程。
而题目中最重要的便是gcd公因数函数,可以使用__gcd,也可以手写。
CPP
int gcd(int a , int b)
{
    int u;
    while(b != 0)
	{
        u = a % b;//辗转相除法
        a = b;
        b = u;
    }
    return a;
}
这里比较偏向于数学成绩更好的。
接下来是韦达定理。 当ab=xab=xx=ab=ab\sqrt{x}=\sqrt{ab}=\sqrt{a}\sqrt{b}
所以我们举个例子: x=72,a=36,b=2,化简得72=62x=72时,取a=36,b=2,化简得\sqrt{72}=6\sqrt{2} 当你想到这个时,就应该能拿30分了,即特殊性质B。
随后考虑特殊性质A。 特殊性质A为“b=0”,所以接下来我们又要化简式子了 ax2+bx+c=0ax²+bx+c=0化简得ax2+c=0ax²+c=0,所以x=ac/ax=\sqrt{-ac}/a,所以特殊性质B也会解了。
接下来跳过特殊性质C,直接考虑AC。
AC思路其实就是把性质ABC全考虑,再考虑小数就行了。 int转double可以这样。
CPP
int x = 1;
x *= 1.0;
把他转为double再按照上面的思路就行了。
用两个个函数处理输出。
除法如下
CPP
void solve(int p , int q)
{
    if(p * q < 0) cout<<'-';
    if(p < 0) p = 0 - p;
    if(q < 0) q = 0 - q;
    int g = gcd(p , q);
    if(g == q) cout << p/g;
    else cout << p/g << '/' << q/g;
    return;
}
平方根如下
CPP
void solve2(int p , int q)
{
    if(p < 0) p = -p;
    if(q < 0) q = -q;
    int u = 1;
    for(int i = sqrt(p); i >= 2; i--) 
	{
        if(p % (i * i) == 0)
		{
            p = p / (i * i);
            u = u * i;
            break;
        }
    }
    int g = gcd(u , q);
    u = u / g;
    q = q / g;
    if(u != 1) cout << u << "*";
    if(p != 1) printf("sqrt(%d)" , p);
    if(q != 1) cout << "/" << q;
}

接下来就是最重要的主函数。
主函数中一个while输入输出。再按照上面的程序连起来。 考虑三种情况。
CPP
    double ans1 = 1.0 * (-b + q) / (2 * a);
    double ans2 = 1.0 * (-b - q) / (2 * a);
    if(ans1 > ans2) 
    {
        if(-b + q == 0) 
        {
	    cout << 0;
	}
        else 
        {
	    solve(-b + q , 2 * a);
	    }
    } 
有三种以上情况请自己推。
连起来就是AC了。

回复

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

正在加载回复...