level 1
program test010;
procedure DivModMinus2(inp:LongInt;var Quo:LongInt;var Mdl:LongWord);
begin
Mdl:=inp and 1;// inp mod 2
dec(inp, Mdl);
Quo:=inp div -2;
end;
procedure DivModMinusPow2(inp,expn:LongInt;var Quo:LongInt;var Mdl:LongWord);
begin
Mdl:=inp and (1 shl expn-1);// inp mod 2**expn
dec(inp, Mdl);
Quo:=inp div -(1 shl expn);
end;
procedure DivModSign(inp,bas:LongInt;var Quo:LongInt;var Mdl:LongWord);
begin
if bas=0 then
begin
Quo:=-1;
Mdl:=$FFFFFFFF;
exit;
end;
Mdl:=inp mod abs(bas);
dec(inp, Mdl);
Quo:=inp div bas;
end;
function IntToMinusBin(inp:LongInt):string;
const
BinDigitChr:array [0..1] of Char=('0', '1');
var
j:LongWord=0;
Mdl:LongWord;
ChrArr:array [0..35] of Char;
begin
if inp=0 then
begin
IntToMinusBin[0]:=#1;
IntToMinusBin[1]:='0';
exit;// exit('0');
end;
while inp<>0 do
begin
//DivModMinus2(inp,inp,Mdl);
Mdl:=inp and 1 ;// inp mod 2
dec(inp, Mdl);
inp:=inp div -2;
ChrArr[j]:=BinDigitChr[Mdl];
inc(j);
end;
IntToMinusBin[0]:=#0;
while j>0 do
begin
dec(j);
inc(IntToMinusBin[0]);
IntToMinusBin[Byte(IntToMinusBin[0])]:=ChrArr[j];
//result=result+ChrArr[j]
end;
end;
var
LoopNum:LongInt;
begin
for LoopNum:=-16 to 16 do
WriteLn(IntToMinusBin(LoopNum));
end.
2016年07月05日 04点07分
4
level 1
和普通的进制数显示一样,但要注意这里的余数必须是正数 (0..1) ,而且商要满足被除数-余数=商*除数。
这里字符串后加字符的写法有点复杂,是为了减少(默认情况下)内部转换函数的调用。
严格来计算机里数字都是二进制的,十进制转负二进制还需要“十进制字符串转成整数”的代码。不过既然 Pascal 自带了 Read/ReadLn/ReadStr ,我们就不用写了。
2016年07月05日 04点07分
5
程序是不是写得太烦了?
2016年07月06日 09点07分
@列宁2003 进制转换这种简单的功能可能会被调用很多次。实现时避免调用其它函数还是有效率提升的……如果编译时命令行加上优化的参数,编译器应该能自动优化,但NOI/NOIP默认是不加的……
2016年07月06日 09点07分
level 5
有必要这么烦吗?
var s:string;
ch:string[1];
n,k:longint;
begin
assign(input,'base.in');reset(input);
assign(output,'base.out');rewrite(output);
readln(n);
repeat
k:=abs(n) and 1;
str(k,ch);
s:=ch+s;
if n<0 then n:=(-n+1)>>1 else n:=-(n>>1);
until n=0;
writeln(s);
close(input);close(output);
end.
2016年07月06日 14点07分
7
嗯,你这个更清晰一点。不过字符串从前面开始拼接的时间复杂度是 O(L^2) ,从后面拼接是 O(L)。假如字符串很长的话效率区别会比很明显(当然实际上不是)。所以我才加了个字符栈…
2016年07月06日 15点07分