【问题描述】
给定两个分数(真分数或假分数) a/b,c/d,且满足 a/b < c/d,你的任务是求 a/b+c/d 的最简分数 和 求这两个分数的中间分数 x/y。中间分数x/y满足:
1、x,y 均为正整数;
2、a/b < x/y < c/d;
3、所有满足2式的(x,y)对中 x+y 最小。
【输入格式】
四个正整数:a, b, c, d 。
【输出格式】
第 1 行:输出a/b+c/d的最简分数。
第 2 行:输出中间分数x/y。
【输入样例】
【样例1】
1 4 1 2
【样例2】
9 10 14 15
【输出样例】
【样例1】
3/4
1/3
【样例2】
11/6
10/11
【数据范围】
0 < a,b,c,d < 100,000,000
【问题分析】
- 分数加减法模拟人工计算,均视作异分母分数进行同分分子相加后同时约掉分子分母的最大公因数既可以得到最简分数
a/b+c/d=(a*c+d*b)/b*d
void plus1(long long a,long long b,long long c,long long d)//为了避免计算过程中溢出,于是统一都为long long
{
long long x,y;
y=b*d;x=a*d+b*c;
long long l=gcd(x,y);
y/=l;x/=l;
cout<<x<<'/'<<y<<endl;
}
2.对于中间分数的理解
a/b < x/y < c/d
==> a/b*y < x < c/d*y
由题
①x、y均为整数,所以x最小为 a/b*y +1
②x+y需要最小,因此y=1开始枚举,每次x=a/b*y +1,然后判断x < c/d*y
若满足,则同时符合以上两个条件,则输出所得x、y
【代码细节】
虽然由数学可推出 a/b*y < x < c/d*y,然而因为计算机对与‘/’的规则的定义,因此不能用a/b*y,需要a*1.0,否则会出现x=1/3*y=0的情况;
同样,对于x < c/d*y的判断,直接比会有精度损失,这就可以直接利用分数比大小的方法–>交叉相乘法
long long p,q;//p分母q分子
for(p=1;;p++)
{
long long x=a*1.0/b*p;
q=x+1;
if(q*d<c*p){//交叉相乘法比大小
cout<<q<<'/'<<p;
return 0;
}
}
Writtrn By Mr.Shadow from CQYZ