Em viết chương trình thực hiện tính tổng hai phân số a/b + c/d. Với 1 ≤ a, b, c, d ≤ 1010). Lưu ý: Các phân số luôn xác định và kết quả viết dưới dạng rút gọn. Dữ liệu nhập:gồm nhiều dòng, mỗi dòng là bốn số nguyên theo thứ tự là a, b, c, d. Kết quả: In ra nhiều dòng, mỗi dòng là tổng của 2 phân số. Pascal
1 câu trả lời
// Mình dùng bignum vì sợ nếu chỉ cần 2 số tầm 10^10 thì
// nó sẽ không bị runtime error (exit code)
uses crt;
type bignum = string;
var a, b, c, d:int64;
tmp:bignum;
x, y:bignum;
function cmp(a, b:bignum):boolean;
begin
if a = b then exit(true);
if length(a) = length(b) then
exit(a > b);
exit(length(a) >= length(b));
end;
function add(a, b:bignum):bignum;
var ans:bignum;
rem, i, tmp:longint;
begin
rem:=0; ans:='';
while length(a) < length(b) do a:='0' + a;
while length(b) < length(a) do b:='0' + b;
for i:=length(a) downto 1 do
begin
tmp:=ord(a[i]) + ord(b[i]) - 96 + rem;
rem:=tmp div 10;
tmp:=tmp mod 10;
ans:=chr(tmp + 48) + ans;
end;
if rem = 1 then ans:='1' + ans;
exit(ans);
end;
function sub(a, b:bignum):bignum;
var c:bignum;
s, br, i:longint;
begin
br:=0; c:='';
while length(a) < length(b) do a:='0' + a;
while length(a) > length(b) do b:='0' + b;
for i:=length(a) downto 1 do
begin
s:=ord(a[i]) - ord(b[i]) - br;
if s < 0 then
begin
s:=s + 10;
br:=1;
end
else br:=0;
c:=chr(s + 48) + c;
end;
while (c[1] = '0') and (length(c) > 1) do delete(c, 1, 1);
exit(c);
end;
function mul(a, b:int64):bignum;
var res:array[0..20] of int64;
s:bignum;
cnt, i:byte;
begin
for i:=0 to 20 do res[i]:=0;
cnt:=20; s:='';
while a <> 0 do
begin
inc(res[cnt], (a mod 10) * b);
a:=a div 10;
dec(cnt);
end;
for i:=20 downto 1 do
begin
inc(res[i - 1], res[i] div 10);
res[i]:=res[i] mod 10;
end;
for i:=1 to 20 do
s:=s + chr(res[i] + 48);
while (s[1] = '0') and (length(s) > 1) do delete(s, 1, 1);
exit(s);
end;
function divmod(a, b:bignum; mode: byte):bignum;
var kb:array[0..11] of bignum;
c, hold:bignum;
i, k:longint;
begin
kb[0]:='0';
for i:=1 to 11 do
kb[i]:=add(kb[i - 1], b);
hold:=''; c:='';
for i:=1 to length(a) do
begin
hold:=hold + a[i];
k:=1;
while cmp(hold, kb[k]) do inc(k);
c:=c+chr(k - 1 + 48);
hold:=sub(hold, kb[k - 1]);
if hold[1] = '0' then delete(hold, 1, 1);
end;
if length(hold) = 0 then hold:='0';
if mode = 2 then exit(hold);
while (c[1] = '0') and (length(c) > 1) do delete(c, 1, 1);
exit(c);
end;
function gcd(a, b:bignum):bignum;
var tmp:bignum;
begin
while b <> '0' do
begin
tmp:=b;
b:=divmod(a, b, 2);
a:=tmp;
end;
exit(a);
end;
begin
clrscr;
while not eof do
begin
readln(a, b, c, d);
x:=add(mul(a, d), mul(b, c));
y:=mul(b, d);
tmp:=gcd(x, y);
writeln(divmod(x, tmp, 1), '/', divmod(y, tmp, 1));
end;
end.