1 条题解

  • 3
    @ 2024-8-25 17:51:58

    题目传送门

    前置知识

    一元二次方程与二次根式知识请自行学习 一元二次方程的解法 二次根式 (注:以上链接可能不够清楚,勿喷)

    题目分析

    纵观全文,题意为判断一元二次方程是否有实数解,若有,则打印最大的答案。

    这是一道模拟题,模拟现实写方程的解的格式。因而有大量细节要注意。具体就写在代码里了。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    int t,m,a,b,c;
    bool zs[1005];
    double delta;
    
    // 素数筛
    void z(){
    	for(int i=2;i<=1000;i++){
    		if(zs[i]) continue;
    		for(int j=2;j;j++){
    			if(i*j>1000) break;
    			zs[i*j]=1;
    		}
    	}
    }
    // 输出题目中的“{p}/{q}” 
    void out(int x,int y,bool flag){
    	if(flag==1&&x==0) return; // 此步是为了防止输出类似 02*sqrt(3) 的情况 
    	if(y<0) x=-x,y=-y;
    	if(x%y==0) printf("%d",x/y);
    	else {
    		// 约分 
    		int d=__gcd(x,y);
    		x/=d;y/=d;
    		if(y<0) x=-x,y=-y;
    		printf("%d/%d",x,y);
    	}
    }
     //  化简二次根式
    int pg(int x){
    	int ans=1; // 记录题目中的“{q2}” 
    	if(x==(int)sqrt(x)*(int)sqrt(x)) ans=sqrt(x);
    	else {
    		for(int i=2;i<=1000;i++){
    			int cnt=0; // 记录对于某个素数,x有几个 
    			if(x<i) break;
    			if(zs[i]) continue;
    			while(x%i==0&&x>1){
    				x/=i;cnt++;
    			}
    			// 下面需有二次根式知识储备,不会的要先学习 
    			if(cnt%2==1) cnt--,x*=i;
    			cnt/=2;
    			ans*=pow(i,cnt);
    		}
    	}
    	return ans;
    }
    
    int main(){
    	z(); // 创建素数表 
        cin >> t >> m;
        while(t--){
        	cin >> a >> b >> c;
        	delta=b*b-4*a*c; // 由题意得判根公式 
        	if(delta<0){
        		cout << "NO\n"; // 注意两个字母都要大写 
        		continue;
    		}
    		if(delta==0){
    			out(-b,2*a,0);
    		}
    		
    		if(delta>0){
    			int kf=pg(delta); //  化简二次根式 
    			delta/=kf*kf;
    			// 有理数
    			if(delta==1){  
    				int x,y=2*a;
    				// 以下2行是找最大分母 
    				if(y>0) x=-b+kf;
    				else x=-b-kf;
    				out(x,y,0);
    			} 
    			// 无理数 
    			else {
    				out(-b,2*a,1);
    				if(b!=0) cout << '+'; // 后半部分一定为正,所以直接加 
        			int x=kf,y=abs(2*a);
    				int d=__gcd(x,y);
    				x/=d;y/=d;
    				if(x!=1) cout << x << '*'; // 避免出现 1* 的情况 
    				// 避免出现根号1的情况 
    				if(delta!=1){
    					cout << "sqrt(" << delta << ')';
    				}
    				if(y!=1) cout << '/' << y; // 避免出现 1* 的情况 
    			}
    		}
    		cout << "\n";
    	}
        return 0;
    }
    

    可能还有一些细节没写出,麻烦评论区指出。 写题解不宜,麻烦给个赞 谢谢观看!!

    • 1

    信息

    ID
    17
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    2
    上传者