zoukankan      html  css  js  c++  java
  • 模拟题3

    原题地址:http://oj.tsinsen.com/ViewGProblem.html?gpid=-1000001014###

    问题描述
    给定n个十六进制正整数,输出它们对应的八进制数。

    输入格式
    输入的第一行为一个正整数n (1<=n<=10)。
    接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

    输出格式
    输出n行,每行为输入对应的八进制正整数。

    【注意】
    输入的十六进制数不会有前导0,比如012A。
    输出的八进制数也不能有前导0。

    样例输入
    2
    39
    123ABC

    样例输出
    71
    4435274

    【提示】
    先将十六进制数转换成某进制数,再由某进制数转换成八进制。

    这道题正解是16进制转为2进制然后转为8进制

    一开始打了一个转化成10进制的,需要打x个高精度,

    最可怕的,复杂度是length*length的……无压力超时

    正解如下:

    其中,delete的操作不可省略

    pascal了copy函数copy(s,k,kk)

    当k小于0时按0计,当k+kk-1大于length时截取到length

    这两种情况都不会报错,而不加任何处理会出错,比如FF(16进制)会变成77(八进制)

    正确的应该是17

    其余解释在代码内部

    正解
     1 program sky;
    2 type
    3 st = string[3];
    4 var
    5 l,ll,i,j,k : longint;
    6 n,tp,t : longint;
    7 a,ch : array[0..1000001] of byte;
    8 s,ss : ansistring;
    9 tps : st;
    10 procedure print(tps: st );{可能麻烦了一些,欢迎交流,给出更简洁的方法}
    11 begin
    12 tp:=0; inc(t); {每次都需要初始化的变量,记得初始化是个好习惯}
    13 ll:=length(tps);
    14 if ll=1 then begin ch[t]:=1; exit; end;
    15 if ll=2 then
    16 begin
    17 if tps[2]='1' then ch[t]:=3 else ch[t]:=2;
    18 exit;
    19 end;
    20 if tps[3]='1' then inc(tp);
    21 if tps[2]='1' then inc(tp,2);
    22 if tps[1]='1' then inc(tp,4);
    23 ch[t]:=tp;
    24 end;
    25 begin
    26 readln(n);
    27 for i:=1 to n do
    28 begin
    29 readln(s);
    30 l:=length(s); t:=0;{同样,t也需要初始化}
    31 ss:='';
    32 for j:=1 to l do
    33 begin
    34 if ord(s[j])>64 then a[j]:=ord(s[j])-65+10
    35 else a[j]:=ord(s[j])-48;
    36 for k:=4 downto 1 do
    37 if 1<<(k-1) and a[j]<>0 then ss:=ss+'1'
    38 else ss:=ss+'0';
    39 end;
    40 j:=4*l;{可以直接对ss取length}
    41 while ss[1]='0' do begin delete(ss,1,1); dec(j); end;
    42 while j>0 do
    43 begin
    44 tps:=copy(ss,j-2,3);
    45 delete(ss,j-2,3);{一定要delete或相关处理}
    46 dec(j,3);
    47 print(tps);
    48 end;
    49 for j:=t downto 1 do write(ch[j]);{ch数组是倒着的……}
    50 writeln;
    51 end;
    52 end.


    由于十进制的打法花费了我很长时间……

    所以也贴上来吧,虽然会超时

    现在正在研究打对拍程序

    等正确性验证后会对此文章进行修改

    解释在里面有

    View Code
     1 program sky;
    2 var
    3 a,ans,c,tp,print:array[0..500000] of longint;
    4 ltp,lltp,len,tot:longint;
    5 s:ansistring;
    6 l,i,iii,j,ii,n:longint;
    7 procedure cheng;{高精乘单精}
    8 begin
    9 for ii:=1 to ltp+4 do c[ii]:=0;
    10 for ii:=1 to ltp do
    11 begin
    12 inc(c[ii],tp[ii]*a[i]);{……不要用都不用a[i]}
    13 inc(c[ii+1],c[ii] div 10);
    14 c[ii]:=c[ii] mod 10;
    15 end;
    16 end;
    17 procedure jia;{高精加高精}
    18 begin
    19 if c[ltp+1]<>0 then lltp:=ltp+1 else lltp:=ltp;{不能再cheng里直接inc(ltp),ltp的意义是tp数组的位数}
    20 if len<lltp then len:=lltp;
    21 for ii:=1 to len do
    22 begin
    23 inc(ans[ii],c[ii]);
    24 inc(ans[ii+1],ans[ii] div 10);
    25 ans[ii]:=ans[ii] mod 10;
    26 end;
    27 if ans[len+1]<>0 then inc(len);
    28 end;
    29 procedure get;{更新存16的若干次方的数组tp1}
    30 begin
    31 for ii:=1 to ltp+4 do c[ii]:=0;
    32 for ii:=1 to ltp do
    33 begin
    34 inc(c[ii],tp[ii]*16);
    35 inc(c[ii+1],c[ii] div 10);{既然是转十进制就div10吧……}
    36 c[ii]:=c[ii] mod 10;{同理……}
    37 end;
    38 while c[ltp+1]<>0 do inc(ltp);
    39 for ii:=1 to ltp do tp[ii]:=c[ii];
    40 end;
    41 procedure chu;{高精除单精}
    42 begin
    43 ans[0]:=0;{初始化}
    44 if ans[len]<8 then begin inc(ans[len-1],ans[len]*10); dec(len); end;
    45 for ii:=len downto 1 do
    46 begin
    47 ans[ii-1]:=ans[ii-1]+(ans[ii] mod 8)*10;
    48 ans[ii]:=ans[ii] div 8;
    49 end;
    50 end;
    51 procedure make;
    52 begin
    53 l:=length(s); tot:=0;
    54 for i:=1 to len+5 do ans[i]:=0;{不要范很2的错误,比如一直ans[len]:=0}
    55 len:=0;
    56 for i:=1 to l do
    57 if ord(s[i])>64 then a[l-i+1]:=ord(s[i])-65+10
    58 else a[l-i+1]:=ord(s[i])-48;
    59 for i:=1 to ltp+4 do tp[i]:=0;{初始化}
    60 tp[1]:=1; ltp:=1;{初始化}
    61 for i:=1 to l do
    62 begin {l*l的复杂度}
    63 cheng;
    64 jia;
    65 get;
    66 end;
    67 while len>0 do begin chu; inc(tot); print[tot]:=ans[0] div 10; end;{div10是因为之前乘了一个10}
    68 for i:=tot downto 1 do write(print[i]);
    69 writeln;
    70 end;
    71 begin
    72 assign(input,'tiaoshi.in'); reset(input);
    73 readln(n);
    74 for iii:=1 to n do
    75 begin
    76 readln(s);
    77 make;
    78 end;
    79 end.

    skysun原创,转载请注明出处,http://www.cnblogs.com/skysun

  • 相关阅读:
    第十六周个人作业
    排球比赛积分程序
    本周个人总结
    本周个人总结
    排球积分规则
    我与计算机
    排球计分(实践)
    观后感
    18周 个人作业
    总结
  • 原文地址:https://www.cnblogs.com/skysun/p/2433675.html
Copyright © 2011-2022 走看看