赞
踩
题目要求
本题的要求很简单,就是求N个数字的和。
麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N(≤100)。
随后一行按格式a1/b1 a2/b2…给出N个有理数。
题目保证所有分子和分母都在长整型范围内。
另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分
分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例1:
5
2/5 4/15 1/30 -2/60 8/3
输出样例1:
3 1/3
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24
做这道题时也是绕了很多弯路,一开始的想法相当的麻烦,但是有办法总比没办法好。于是,我就按照自己的思路:输入的分数,我是按字符串读取的,每两个字符串处理之后(处理为分子1,分母1,分子2,分母2,其实就是把数字从字符串中截取出来),相加,得到一个分数。然后判断这个分子的绝对值是否大于分母。如果大的话,就取整(取得的整数为全局变量)再求分数部分。最后是把分数约分化简(我约分化简了两次,怕没化到最简)。在这个字符串相加函数最后返回分数字符串。在主函数中,
string x = add(data[0],data[1]);
for(int i=2;i<N;i++){
x = add(x,data[i]);
}
。要说明一下,我设了一个全局的整数、分子、分母。(可能也没多大用吧,但是也不想改了)。
代码如下:
#include<iostream> #include<sstream> #include<cmath> #include<string> using namespace std; long int zhengshu,fenzi,fenmu; string add(string s1,string s2){ long int a,b,c,d;long int temp;stringstream ss; temp = s1.find_first_of('/',0); ss<<s1.substr(0,temp); ss>>a; ss.clear(); ss<<s1.substr(temp+1,s1.length()-temp-1); ss>>b; ss.clear(); temp = s2.find_first_of('/',0); ss<<s2.substr(0,temp); ss>>c; ss.clear(); ss<<s2.substr(temp+1,s2.length()-temp-1); ss>>d; long int fenzi1,fenmu1; fenzi1 = a*d + c*b; fenmu1 = b*d; if(abs(fenzi1)> fenmu1){ zhengshu += fenzi1/fenmu1; fenzi1 = fenzi1 - (fenzi1/fenmu1)*fenmu1; }else if(fenzi1 == fenmu1){ zhengshu += 1; fenzi1 = 0; fenmu1 = 1; }else if((fenzi1 + fenmu1) == 0){ zhengshu -= 1; fenzi1 = 0; fenmu1 = 1; } int k = 0; if(fenzi1 < 0){ k = 1; fenzi1 = abs(fenzi1); } //约分 化简 for(int i=2;i<=fenzi1;i++){ if(fenzi1%i==0 && fenmu1%i==0){ fenzi1 = fenzi1/i; fenmu1 = fenmu1/i; } } for(int i=2;i<=fenzi1;i++){ if(fenzi1%i==0 && fenmu1%i==0){ fenzi1 = fenzi1/i; fenmu1 = fenmu1/i; } } if(k == 1) fenzi1 = -fenzi1; fenmu = fenmu1; fenzi = fenzi1; ss.clear(); string m; ss<<fenzi; ss>>m; ss.clear(); string n; ss<<fenmu; ss>>n; return m+"/"+n; } int main(){ int N; cin>>N; string data[N]; for(int i=0;i<N;i++){ cin>>data[i]; } string x = add(data[0],data[1]); for(int i=2;i<N;i++){ x = add(x,data[i]); } if(fenzi == 0) cout<<zhengshu; else if(zhengshu == 0) cout<<fenzi<<"/"<<fenmu; else if(zhengshu > 0 && fenzi < 0){ if(zhengshu-1 != 0) cout<<zhengshu-1<<" "<<fenzi + fenmu<<"/"<<fenmu; else cout<<fenzi + fenmu<<"/"<<fenmu; } else if(zhengshu < 0 && fenzi > 0) if(zhengshu+1 != 0) cout<<zhengshu+1<<" "<<fenmu-fenzi<<"/"<<fenmu; else cout<<fenmu-fenzi<<"/"<<fenmu; else cout<<zhengshu<<" "<<abs(fenzi)<<"/"<<fenmu; return 0; }
因为,我的整数部分和分数部分是分开计算的,所以会有,整数为正,分数为负;整数为负,分数为整的情况QwQ(改了超级久,才发现,我太难了)。
但是,我看了别人的代码之后,才知道自己的代码有多垃圾QwQ。如下,是我按照别人的思路打的代码。
#include<iostream> #include<cmath> using namespace std; struct Node{ long int zi; long int mu; }data; //最大公因数 int Max(int a,int b){ int small = min(a,b); int big = max(a,b); int temp; if(big%small == 0)return small; while(big%small){ temp = big%small; big = small; small = temp; } return small; } //最小公倍数 int Min(int a,int b){ return a*b/Max(a,b); } int main(){ int N; cin>>N; Node n[N]; char c; for(int i=0;i<N;i++){ cin>>n[i].zi>>c>>n[i].mu; } //分母最小公倍数 int min = n[0].mu; for(int i=1;i<N;i++){ min = Min(min,n[i].mu); } int sum = 0; //所有分子的 和 for(int i=0;i<N;i++){ sum += n[i].zi*min/n[i].mu; } if(sum < 0){ cout<<"-"; } if(sum == 0){ cout<<0; return 0; } sum = abs(sum); int max = Max(sum,min); sum /= max; min /= max; if(sum >= min){ if(sum - (sum/min)*min != 0) cout<<sum/min<<" "<<(sum - (sum/min)*min)<<"/"<<min<<endl; else cout<<sum/min; } else{ cout<<sum<<"/"<<min; } return 0; }
只要多练习,思路就会变得和大佬一样。
一个集坚强与自信于一身的菇凉。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。