题目要求
本题的要求很简单,就是求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;
}
只要多练习,思路就会变得和大佬一样。
一个集坚强与自信于一身的菇凉。