洛谷 P1017 进制转换

P1017 进制转换

先从正进制开始考虑。

例如二进制:

18=1*2^4+0*2^3+0*2^2+1*2^1+0*2^0=0+2(1+2(0+2(0+2(1))))

k=a[n]*2^n+a[n-1]*2^(n-1)+...+a[0]*2^0=a[0]+2(a[1]+2(...+2(a[n])...)...)

短除法将k转换为二进制就是把k除以二,留下商,记录下余数,然后再对商执行此操作,不断重复直到数变为0,再将所有余数倒序输出,根据此式可看出其原理就是第i次除以二时的余数显然就是a[i-1]。

然后考虑负进制。

如负二进制:

k=a[0]-2(a[1]-2(...-2(a[n])...)...)

根据题意,a[0],a[1],...,a[n] >=0

由此可得出将k转换为负二进制的短除法方法:(开始时i=0)

①寻找一个整数p,使得 -2p≤k 且-2p 在可能的范围内最大,记录下k-(-2p),即为a[i]

②如果p为0则进入下一步,如果不为0则p->k(将p赋值给k),i++,然后回到第①步

③得出答案:n=i,k=a[n]*(-2)^n+a[n-1]*(-2)^(n-1)+...+a[0]*(-2)^0

(其它进制可由此类比)

另外,还有一点需要注意:得到p可以用取模运算,但是pascal、c++等对负数的取模有点儿不一样,需要注意一下。

const sz:array[0..20] of char=('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K');
var a:array[1..1000] of integer;
i,i1,j,n1,n,r,t1,t2:longint;
begin
  readln(n1,r);
  n:=n1;
  while n<>0 do
  begin
    inc(i1);
    t1:=n div r;
    t2:=n mod r;
    if t2<0 then inc(t1);
    a[i1]:=n-r*t1;
    n:=t1;
  end;
  write(n1,'=');
  for i:=i1 downto 1 do
    write(sz[a[i]]);
  write('(base',r,')');
end.


你可能感兴趣的:(数论)