noip2011初赛-大整数开方
2015-08-23 17:27
330 查看
noip2011C_4_2(大整数开方)输入一个正整数n(1<=n<=10^100),试用二分法计算它的平方根的整数部分。
const SIZE=200; type hugeint=record len:integer; num:array[1..SIZE] of integer; end; var s:string; i:integer; target,left,middle,right:hugeint; function add(a,b:hugeint):hugeint; 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]:=ans.num[i]+a.num[i]+b.num[i]; 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 times(a,b:hugeint):hugeint; var i,j:integer; ans:hugeint; begin fillchar(ans,sizeof(ans),0); for i:=1 to a.len do begin for j:=1 to b.len do begin ans.num[i+j-1]:=ans.num[i+j-1]+a.num[i]*b.num[j]; end; end; for i:=1 to a.len+b.len do begin ans.num[i+1]:=ans.num[i+1]+ans.num[i] div 10; ans.num[i]:=ans.num[i] mod 10; 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 average(a,b:hugeint):hugeint; 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]+(ans.num[i] mod 2)*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; 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 inc(ans.len); plustwo:=ans; end; function over(a,b:hugeint):boolean; var i:integer; begin if (a.len<b.len) 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 begin target.num[i]:=ord(s[target.len-i+1])-ord('0'); end; fillchar(left.num,sizeof(left.num),0); left.len:=1; left.num[1]:=1; right:=target; repeat middle:=average(left,right); if over(times(middle,middle),target) then right:=middle else left:=middle; until over(plustwo(left),right); for i:=left.len downto 1 do write(left.num[i]); writeln; end.
相关文章推荐
- SIFT算法详解
- 编程之美1.13 威佐夫博奕拓展的分析与论证
- jvm参数调优
- php大力力 [008节]局部表量
- C,C++开源项目中的100个Bugs
- [LeetCode] Insert Interval
- eclipse中使用反射机制时应该注意的问题
- java 时间函数中的一个bug?
- noip2011初赛-子矩阵
- 将iPhone投影到Mac上
- 2044 一只小蜜蜂...【递推】
- JAVA BigDecimal 小数点处理
- 大龄屌丝自学笔记--Java零基础到菜鸟--009
- pptv首页导航效果
- XCODE常用的插件
- noip2010初赛-哥德巴赫猜想
- Arrays
- 例题9-8 颜色的长度 UVa1625
- 相亲会成家长会
- Android基础UI之TextView实现跑马灯效果