1 条题解
-
3
前置知识
一元二次方程与二次根式知识请自行学习 一元二次方程的解法 二次根式 (注:以上链接可能不够清楚,勿喷)
题目分析
纵观全文,题意为判断一元二次方程是否有实数解,若有,则打印最大的答案。
这是一道模拟题,模拟现实写方程的解的格式。因而有大量细节要注意。具体就写在代码里了。
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
- 上传者