(大整数开方)输入一个正整数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.