本题的要求很简单,就是求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
代码有点乱,不过思路很清楚,多想几组特殊的测试数据。
#include <iostream>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#define ll long long
using namespace std;
string str[101];
int n;
struct data
{
ll x;
ll y;
bool flag; //判断符号
} a[1010];
ll change(ll x, ll y, bool flag)
{
ll n = x, m = y;
if (x < y)
{
ll t = x;
x = y;
y = t;
}
while (y)
{
ll m = x % y;
x = y;
y = m;
}
if (flag == false)
return x;
return n / x * m;
}
int main()
{
while(cin >> n)
{
for (int i = 0; i < n; i ++)
{
cin >> str[i];
int j = 0;
if (str[i][0] == '-')
{
j ++;
a[i].flag = 1;
}
a[i].x = a[i].y = 0;
for (j; j < str[i].length(); j ++)
{
if (str[i][j] == '/')
break;
a[i].x = a[i].x * 10 + str[i][j] - '0';
}
for (j ++; j < str[i].length(); j ++)
a[i].y = a[i].y * 10 + str[i][j] - '0';
// cout << a[i].x << " " << a[i].y << " " << a[i].flag << endl;
}
for (int i = 1; i < n; i ++)
{
// 求出最小公倍数
ll m = change(a[i - 1].y, a[i].y, true);
ll k = m / a[i - 1].y * a[i - 1].x;
ll t = m / a[i].y * a[i].x;
// 都是负数
if (a[i].flag == 1 && a[i - 1].flag == 1)
{
k = k + t;
// 求出最大公约数
ll s = change(k, m, false);
a[i].x = k / s;
a[i].y = m / s;
a[i].flag = 1;
}
// 一个负数
else if (a[i].flag == 1 && a[i - 1].flag == 0)
{
k = k - t;
ll s = change(k, m, false);
a[i].x = k / s;
a[i].y = m / s;
if (k < 0)
{
a[i].flag = 1;
k = -k;
}
else
a[i].flag = 0;
}
else if (a[i].flag == 0 && a[i - 1].flag == 1)
{
k = t - k;
ll s = change(k, m, false);
a[i].x = k / s;
a[i].y = m / s;
if (k < 0)
{
a[i].flag = 1;
k = -k;
}
else
a[i].flag = 0;
}
// 都是正数
else
{
k = k + t;
// 求出最大公约数
ll s = change(k, m, false);
a[i].x = k / s;
a[i].y = m / s;
a[i].flag = 0;
}
// cout << i << " " << a[i].x << " " << a[i].y << " " << a[i].flag << endl;
}
if (a[n - 1].flag == 1)
cout << "-";
ll s = change(a[n - 1].x, a[n - 1].y, false);
a[n - 1].x = a[n - 1].x / s;
a[n - 1].y = a[n - 1].y / s;
if (a[n - 1].x > a[n - 1].y)
{
cout << int(a[n - 1].x / a[n - 1].y);
a[n - 1].x = a[n - 1].x % a[n - 1].y;
if (a[n - 1].x == 0)
{
cout << endl;
continue;
}
else
cout << " ";
}
if (a[n - 1].x != 0)
cout << a[n - 1].x << "/" << a[n - 1].y << endl;
else
cout << 0 << endl;
// cout << a[n - 1].x << " " << a[n - 1].y << " " << a[n - 1].flag << endl;
}
return 0;
}
/*
3
0/1 0/2 0/3
1
2/10
3
0/1 0/2 5/10
5
2/5 4/15 1/30 -2/60 8/3
2
4/3 2/3
3
1/3 -1/6 1/8
*/