有限小数 解题报告

36 篇文章 0 订阅
35 篇文章 0 订阅
 

题目描述

小J是一个严谨的人,他只能接受有限小数,而总有些数令他不爽,比如0.33...。一天,他发现0.33…在3进制下可以写成0.1,在30进制下可以写成0.A等,于是他坚信所有有理数都可以写成有限小数。然而,不断切换进制是很麻烦的工作,现在小J需要处理若干有理数,你需要告诉他最少需要几进制才能使它们都能写成有限小数。

【数据范围】
100%的数据保证n≤10,000;1≤a,b≤1,000,000,000
【注释】
十六进制使用[0-9,A-F],具体表示方法请参照windows自带计算器

输入格式

第一行一个整数n
接下来n行,每行两个整数a b,表示一个分数a/b

输出格式

一行一个十六进制整数,表示最小进制数

样例输入

样例输入

样例输出

 

直接分解质因数就行,数据没有题目说的那么大。

var su:array[0..1000000] of longint;
a,b:array[0..10000] of longint;
ans:array[0..100000] of int64;
v:array[0..2000000] of boolean;
n,m,i,j,k,sum:longint;
procedure sushu;
var i,j,k:longint;
begin
 for i:=2 to 1000000 do
  if not v[i] then
   begin
    j:=i;
    repeat
     j:=j+i; v[j]:=true;
    until j>1000000;
   end;
 for i:=2 to 1000000 do
  if not v[i] then
   begin
    inc(su[0]); su[su[0]]:=i;
   end;
end;
function gcd(x,y:longint):longint;
var k:longint;
begin
 while y<>0 do
  begin
   k:=x mod y; x:=y; y:=k;
  end;
 exit(x);
end;
procedure find(x:longint);
var i,k:longint;
begin
 k:=x;
 for i:=1 to su[0] do
  {if su[i]>x then exit
  else}//fuck
   begin
    if x mod su[i]=0 then v[i]:=true; {writeln(i,' ',su[0]);}
    while x mod su[i]=0 do
     x:=x div su[i];     if x=1 then exit;
   end;
 if x<>0 then //important 
  begin
   inc(su[0]); su[su[0]]:=x; v[su[0]]:=true; {writeln(k,'  dgd');}
  end;
end;
procedure cheng(x:longint);
var i:longint;
begin
 ans[1]:=ans[1]*x;
 for i:=2 to ans[0] do
  begin
   ans[i]:=ans[i]*x+ans[i-1] div 16;
   ans[i-1]:=ans[i-1] mod 16;
  end;
 {if ans[ans[0]+1]>0 then inc(ans[0]);}
 while ans[ans[0]]>15 do
  begin
   inc(ans[0]); ans[ans[0]]:=ans[ans[0]-1] div 16;
   ans[ans[0]-1]:=ans[ans[0]-1] mod 16;
  end;
end;
begin
 {assign(input,'p1.in'); assign(output,'p1.out');
 reset(input); rewrite(output);}
 readln(n); sushu;
 {for i:=1 to su[0] do
  writeln(su[i]);}
 fillchar(v,sizeof(v),0);
 for i:=1 to n do
  begin
   readln(a[i],b[i]); b[i]:=b[i] div gcd(a[i],b[i]); {writeln(b[i],'    fghf');}
   find(b[i]);
  end;
 ans[0]:=1; ans[1]:=1;
 for i:=1 to su[0] do
  if v[i] then
   begin
   cheng(su[i]);
   {writeln(su[i]);}
   end;
 for i:=ans[0] downto 1 do
  if ans[i]<10 then write(ans[i])
  else write(chr(ord('A')+ans[i]-10));
 {close(input); close(output);}
end.


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值