首页 > 试题广场 >

(大整数开方)输入一个正整数n(1≤n<10100)...

[填空题]
(大整数开方)输入一个正整数n(1≤n<10100),试用二分法计算它的平方根的整数部分。
Const
  SIZE = 200;
Type
  hugeint = Record
    len : Integer;
    num : Array[1..SIZE] Of Integer;
  End;
    //len表示大整数的位数;num[1]表示个位、num[2]表示十位,以此类推
Var
  s : String;
  i : Integer;
  target, left, middle, right : hugeint;
Function times(a, b : hugeint) : hugeint;
// 计算大整数 a 和 b 的乘积
Var
  i, j : Integer;
  ans : hugeint;
Begin
  FillChar(ans, SizeOf(ans), 0);
  For i := 1 To a.len Do
    For j := 1 To b.len Do
    1    := ans.num[i + j - 1] + a.num[i] * b.num[j];
  For i := 1 To a.len + b.len Do
  Begin
    ans.num[i + 1] := ans.num[i + 1] + ans.num[i] DIV 10;
    2;
    If ans.num[a.len + b.len] > 0
    Then ans.len := a.len + b.len
    Else ans.len := a.len + b.len - 1;
  End;
  times := ans;
End;
Function add(a, b : hugeint) : hugeint;
// 计算大整数 a 和 b 的和
Var
  i : Integer;
  ans : hugeint;
Begin
  FillChar(ans.num, SizeOf(ans.num), 0);
  If a.len > b.len
  Then ans.len := a.len
  Else ans.len := b.len;
  For i := 1 To ans.len Do
  Begin
    ans.num[i] := 3;
    ans.num[i + 1] := ans.num[i + 1] + ans.num[i] DIV 10;
    ans.num[i] := ans.num[i] MOD 10;
  End;
  If ans.num[ans.len + 1] > 0
  Then Inc(ans.len);
  add := ans;
End;
Function average(a, b : hugeint) : hugeint;
// 计算大整数 a 和 b 的平均数的整数部分
Var
  i : Integer;
  ans : hugeint;
Begin
  ans := add(a, b);
  For i := ans.len DownTo 2 Do
  Begin
    ans.num[i - 1] := ans.num[i - 1] + (4) * 10;
    ans.num[i] := ans.num[i] DIV 2;
  End;
  ans.num[1] := ans.num[1] DIV 2;
  If ans.num[ans.len] = 0
  Then Dec(ans.len);
  average := ans;
End;
Function plustwo(a : hugeint) : hugeint;
// 计算大整数 a 加 2 后的结果
Var
  i : Integer;
  ans : hugeint;
Begin
  ans := a;
  ans.num[1] := ans.num[1] + 2;
  i := 1;
  While (i <= ans.len) AND (ans.num[i] >= 10) Do
  Begin
    ans.num[i + 1] := ans.num[i + 1] + ans.num[i] DIV 10;
    ans.num[i] := ans.num[i] MOD 10;
    Inc(i);
  End;
  If ans.num[ans.len + 1] > 0
  Then    5;
  plustwo := ans;
End;
Function over(a, b : hugeint) : Boolean;
// 若大整数 a > b 则返回 1, 否则返回 0
Var
  i : Integer;
Begin
  If (6) Then
  Begin
    over := FALSE;
    Exit;
  End;
  If a.len > b.len Then
  Begin
    over := TRUE;
    Exit;
  End;
  For i := a.len DownTo 1 Do
  Begin
    If a.num[i] < b.num[i] Then
    Begin
      over := FALSE;
      Exit;
    End;
    If a.num[i] > b.num[i] Then
    Begin
      over := TRUE;
      Exit;
    End;
  End;
  over := FALSE;
End;
Begin
  Readln(s);
  FillChar(target.num, SizeOf(target.num), 0);
  target.len := Length(s);
  For i := 1 To target.len Do
    target.num[i] := Ord(s[target.len - i + 1]) - 7;
  FillChar(left.num, SizeOf(left.num), 0);
  left.len := 1;
  left.num[1] := 1;
  right := target;
  Repeat
    middle := average(left, right);
    If over(8)
    Then right := middle
    Else left := middle;
  Until over(plustwo(left), right);
  For i := left.len DownTo 1 Do
    Write(left.num[i]);
  Writeln;
End. 

这道题你会答吗?花几分钟告诉大家答案吧!