noip2011初赛-大整数开方

来源:互联网 发布:无线网络控制软件 编辑:程序博客网 时间:2024/06/05 18:10

noip2011C_4_2(大整数开方)输入一个正整数n(1<=n<=10^100),试用二分法计算它的平方根的整数部分。


constSIZE=200;typehugeint=recordlen:integer;num:array[1..SIZE] of integer;end;vars:string;i:integer;target,left,middle,right:hugeint;function add(a,b:hugeint):hugeint;vari:integer;ans:hugeint;beginfillchar(ans.num,sizeof(ans.num),0);if a.len>b.len then ans.len:=a.lenelse ans.len:=b.len;for i:=1 to ans.len dobeginans.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;vari,j:integer;ans:hugeint;beginfillchar(ans,sizeof(ans),0);for i:=1 to a.len dobeginfor j:=1 to b.len dobeginans.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 dobeginans.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.lenelse ans.len:=a.len+b.len-1;end;times:=ans;end;function average(a,b:hugeint):hugeint;vari:integer;ans:hugeint;beginans:=add(a,b);for i:=ans.len downto 2 dobeginans.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;vari:integer;ans:hugeint;beginans:=a;ans.num[1]:=ans.num[1]+2;i:=1;while(i<=ans.len) and (ans.num[i]>=10) dobeginans.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;vari:integer;beginif (a.len<b.len) thenbeginover:=false;exit;end;if (a.len>b.len) thenbeginover:=true;exit;end;for i:=a.len downto 1 dobeginif a.num[i]<b.num[i] thenbeginover:=false;exit;end;if a.num[i]>b.num[i] thenbeginover:=true;exit;end;end;over:=false;end;beginreadln(s);fillchar(target.num,sizeof(target.num),0);target.len:=length(s);for i:=1 to target.len dobegintarget.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;repeatmiddle:=average(left,right);if over(times(middle,middle),target) then right:=middleelse left:=middle;until over(plustwo(left),right);for i:=left.len downto 1 do write(left.num[i]);writeln;end.


0 0
原创粉丝点击