回 帖 发 新 帖 刷新版面

主题:K进制转换

Description 

将输入的一个k进制数转换成m进制数。

Input 

第一行共有二个正整数:k m 数与数之间用一个空格隔开 ( 1 < m , k < 10 ) 
第二行只有一个长度为n的k进制正整数 ( 1 <= n <= 100 )

Output 

只有一行且只有一个m进制的正整数

Sample Input 


2 3
101

Sample Output 


12

Source 

稍难题
好的给分啊!

回复列表 (共12个回复)

沙发

要用pascal的做啊

板凳

只是随手写写罢了,@@@没调哦@@@
program try;
var st:string;
    k,m:shortint;
    sum:qword;
procedure pre;
var i:shortint;
begin
  sum:=0;
  for i:=1 to length(st) do
    sum:=sum+(ord(st[i])-48)*power(k,length(st)-i);
end;
procedure main(x:qword);
begin
  if x>=m then
  begin
    main(x div m);
    write(x mod m);
  end
         else write(x);
end;
begin
  readln(k,m);
  readln(st);
  pre;
  main(sum);
end.
思路:把它先转为10进制再转为相应m进制
BUG:由于2的100次方有n位,故需要高精度乘法,在这里我就不写了哈

3 楼

求你了,帮忙用一下高精度乘法和除法吧,我会乘法,可是不会除法啊!!!!!

4 楼

高精度除法讲解:
program highprecision;
const maxlen=10000; { 数据的最大长度 }
type hp=record {定义一记录数据类型hp}
       len:longint; { 数组的长度 }
       s:array[1..maxlen] of integer;
     end;
var x:array[1..2] of hp; {x[1],x[2]分别用于存储被除数和除数}
    y,w:hp; {y用于存结果,w用于存余数 }
////////////////////过程:输出/////////////////////////
procedure printhp(const p:hp);
var i:longint;
begin
  for i:=p.len downto 1 do
    write(p.s[i]);
end;
///////////////////过程:初始化数据///////////////////
procedure init;
var st:ansistring;
    i,j:longint;
begin
  assign(input,'data.in');
  reset(input);
  for j:=1 to 2 do
  begin
    readln(st);
    x[j].len:=length(st);
    for i:=1 to x[j].len do {将string倒序转换成整型数组}
      x[j].s[i]:=ord(st[x[j].len+1-i])-ord('0');
  end;
  close(input);
end;
//////////////////过程:高精度减法//////////////////////
procedure subtract(a,b:hp;var c:hp); { c:=a-b, a应该>=b }
var i,len:longint;
begin
  fillchar(c,sizeof(c),0);
  if a.len>b.len then len:=a.len { 找到a,b中最长的长度,存到len中 }
                 else len:=b.len;
  for i:=1 to len do {相减,结果存放在c中} 
  begin
    inc(c.s[i],a.s[i]-b.s[i]);
    if c.s[i]<0 then
    begin
      inc(c.s[i],10);
      dec(c.s[i+1]);
    end;
  end;
  while (len>1) and (c.s[len]=0) do {去掉高位的0}
    dec(len); 
  c.len:=len; 
end; 
//////////////////函数:两数组比较大小////////////////// 
function compare(const a,b:hp):integer; { 如果 a>b 函数值>0 如果 a=b 函数值=0 }
var len:longint;
begin
  if a.len>b.len then len:=a.len { 找出a,b中最长的长度 }
                 else len:=b.len;
  while (len>0) and (a.s[len]=b.s[len]) do
    dec(len); { 找出两数组中第一个不相同数据的位子 }
  if len=0 then compare:=0
           else compare:=a.s[len]-b.s[len];
end; 
/////////////////过程:数组移位///////////////////// 
procedure multiply10(var a:hp); { a:=a*10 } 
var i:longint; 
begin
  for i:=a.len downto 1 do
    a.s[i+1]:=a.s[i];
  a.s[1]:=0;
  inc(a.len);
  while (a.len>1) and (a.s[a.len]=0) do
    dec(a.len);
end; 
////////////////过程:相除//////////////////////////// 
procedure divide(a,b:hp;var c,d:hp); { c:=a div b ; d:=a mod b } 
var i,j,len:longint; 
begin 
  fillchar(c,sizeof(c),0); 
  len:=a.len; 
  fillchar(d,sizeof(d),0); 
  d.len:=1; 
  for i:=len downto 1 do
  begin
    multiply10(d);
    d.s[1]:=a.s[i];
    while (compare(d,b)>=0) do
    begin
      subtract(d,b,d);
      inc(c.s[i]);
    end;
  end;
  while (len>1)and(c.s[len]=0) do
    dec(len);
  c.len:=len;
end;
procedure main; 
begin 
  divide(x[1],x[2],y,w); 
end; 
///////////////////过程:输出///////////////// 
procedure out; 
begin
  assign(output,'data.out');
  rewrite(output);
  printhp(y);
  writeln;
  printhp(w);
  close(output);
end; 
////////////////////主程序///////////////////// 
begin 
  init;
  main;
  out; 
end.

另:其他的自己拷贝吧

5 楼

好长呀

6 楼

当然了
加了N多注释。。。。。。。。。

7 楼

不用那么麻烦吧?

8 楼

给你一个思路,不过需要你自己写程序:
1、读入首行两个数K与M,并判断其合法性(必须大于1,且需要小于10)
2、读入一行字符串strOld
3、进制转换:要从strOld结尾开始处理,并从后往前加到strNew里。

重点就是第3步的算法,我们做进一步的细化:
1、初始化余值nMod为0;
2、初始化I为strOld的长度;

3、读取strOld的第I个字符,并转成整型存储到nCurr;
4、将nMod*K加到nCurr中;
5、将nCurr转为M进制串,并除最高位外,其余都加到strNew的左端;
6、将被转成的M进制串的最高位转成整型并存储到nMod中;
7、I自减,如果I不为0则转到3;

8、将nMod加到strNew的左端。

大概就是这样了,具体的代码自己写吧,也好加深印象。如果遇到什么问题我们再讨论如何:)

9 楼

楼上的:不如写个位运算方便??

10 楼

高精整型A进制到B进制应该用不了位运算吧?

我来回复

您尚未登录,请登录后再回复。点此登录或注册