1.铺瓷砖
(tile.cpp/c/pas)
【问题描述】
有一面很长很长的墙。你需要在这面墙上贴上两行瓷砖。你的手头有两种不同尺寸的瓷
砖,你希望用这两种瓷砖各贴一行。瓷砖的长可以用分数表示,贴在第一行的每块瓷砖长度
为 A
B ,贴在第二行的每块瓷砖长度为
C
D 。本问题中你并不需要关心瓷砖的宽度。
如上图所示,两排瓷砖从同一起始位置开始向右排列,两排瓷砖的第一块的左端的缝隙
是对齐的。你想要知道,最短铺多少距离后,两排瓷砖的缝隙会再一次对齐。
【输入】
输入的第 1 行包含一个正整数 T,表示测试数据的组数。
接下来 T 行,每行 4 个正整数 A,B,C,D,表示该组测试数据中,两种瓷砖的长度分
别为 A
B 和
C
D 。
【输出】
输出包含 T 行,第 i 行包含一个分数或整数,表示第 i 组数据的答案。如果答案为分数,
则以“X/Y”的格式输出,不含引号。分数必须化简为最简形式。如果答案为整数,则输出
一个整数 X。
【输入输出样例 1】
tile.in tile.out
2
1 2 1 3
1 2 5 6
1
5/2
见选手目录下的 tile/tile1.in 与 tile/tile1.out
【输入输出样例 1 说明】
对于第一组数据,第一行瓷砖贴 2 块,第二行贴 3 块,总长度都为 1,即在距离起始位
置长度为 1 的位置两行瓷砖的缝隙会再次对齐。
(tile.cpp/c/pas)
【问题描述】
有一面很长很长的墙。你需要在这面墙上贴上两行瓷砖。你的手头有两种不同尺寸的瓷
砖,你希望用这两种瓷砖各贴一行。瓷砖的长可以用分数表示,贴在第一行的每块瓷砖长度
为 A
B ,贴在第二行的每块瓷砖长度为
C
D 。本问题中你并不需要关心瓷砖的宽度。
如上图所示,两排瓷砖从同一起始位置开始向右排列,两排瓷砖的第一块的左端的缝隙
是对齐的。你想要知道,最短铺多少距离后,两排瓷砖的缝隙会再一次对齐。
【输入】
输入的第 1 行包含一个正整数 T,表示测试数据的组数。
接下来 T 行,每行 4 个正整数 A,B,C,D,表示该组测试数据中,两种瓷砖的长度分
别为 A
B 和
C
D 。
【输出】
输出包含 T 行,第 i 行包含一个分数或整数,表示第 i 组数据的答案。如果答案为分数,
则以“X/Y”的格式输出,不含引号。分数必须化简为最简形式。如果答案为整数,则输出
一个整数 X。
【输入输出样例 1】
tile.in tile.out
2
1 2 1 3
1 2 5 6
1
5/2
见选手目录下的 tile/tile1.in 与 tile/tile1.out
【输入输出样例 1 说明】
对于第一组数据,第一行瓷砖贴 2 块,第二行贴 3 块,总长度都为 1,即在距离起始位
置长度为 1 的位置两行瓷砖的缝隙会再次对齐。
对于第二组数据,第一行瓷砖贴 5 块,第二行贴 3 块,总长度都为 5/2 。
分析:
其实就是简单的数学运算,设x个一号砖,y个二号,那么:
l=(a/b)*x=(c/d)*y
x/y=b*c/(a*d)
然后将右式化为最简形式,x和y的最小值就对应出来了,
最后计算l就行了。
参考程序:
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b){
if (!b)return a;
return gcd(b,a%b);
}
int main(){
freopen("tile.in","r",stdin);
freopen("tile.out","w",stdout);
int T;
scanf("%d",&T);
while (T--){
LL a,b,c,d;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
LL t=gcd(b,d);
LL b0=d/t,d0=b/t,lcm1=b/t*d;
LL a0=a*b0,c0=c*d0;
t=gcd(a0,c0);
LL lcm2=a0/t*c0;
t=gcd(lcm1,lcm2);
if (t==lcm1)printf("%lld\n",lcm2/t);
else printf("%lld/%lld\n",lcm2/t,lcm1/t);
}
return 0;
}