题目
Description
输入一个正整数n(1<=n<=10^100),输出n的平方根的整数部分。
Input
正整数n
Output
n的平方根的整数部分
Sample Input
10
Sample Output
3
Data Constraint
n ≤ 1 0 100 n\le10^{100} n≤10100
题解
题目大意
求一个大数的平方根的整数部分
题目分析
如果说 n n n小一点我们可以考虑二分,那么 n n n大了则可以高精度
这题是一个高精度综合板子题,有高精乘、高精除二,高精加一,高精减一,高精加,高精比较
Code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct highcalc
{
int len,num[10005];
};
highcalc l,r,mid,n,ans,res;
char sa[105];
bool small(highcalc x,highcalc y)
{
if (x.len>y.len) return false;
if (x.len<y.len) return true;
for (int i=x.len;i;--i)
{
if (x.num[i]>y.num[i]) return false;
if (x.num[i]<y.num[i]) return true;
}
return true;
}
void Plus(highcalc a,highcalc b,highcalc &c)
{
for (int i=1;i<=max(a.len,b.len);++i)
{
c.num[i]+=a.num[i]+b.num[i];
c.num[i+1]+=c.num[i]/10;
c.num[i]%=10;
}
c.len=max(a.len,b.len);
while (c.num[c.len+1])
{
c.len++;
c.num[c.len+1]+=c.num[c.len]/10;
c.num[c.len]%=10;
}
}
void div2(highcalc &a)
{
if (a.num[1]%2==1) a.num[1]--;
for (int i=a.len;i;--i)
{
a.num[i-1]+=(a.num[i]%2)*10;
a.num[i]/=2;
}
int st=a.len;
while (!a.num[st]) --st;
a.len=st;
}
void mul(highcalc a,highcalc b,highcalc &c)
{
for (int j=1;j<=b.len;++j)
for (int i=1;i<=a.len;++i)
{
c.num[i+j-1]+=a.num[i]*b.num[j];
c.num[i+j]+=c.num[i+j-1]/10;
c.num[i+j-1]%=10;
}
c.len=a.len+b.len-1;
while (c.num[c.len+1])
{
c.len++;
c.num[c.len+1]=c.num[c.len]/10;
c.num[c.len]%=10;
}
}
void add1(highcalc &a)
{
for (int i=1;i<=a.len;++i)
{
if (i==1) a.num[i]++;
a.num[i+1]+=a.num[i]/10;
a.num[i]%=10;
}
if (a.num[a.len+1]) a.len++;
}
void dec1(highcalc &a)
{
for (int i=1;i<=a.len;++i)
{
if (i==1) a.num[i]--;
if (a.num[i]<0) a.num[i]+=10,a.num[i+1]--;
}
while (!a.num[a.len]&&a.len>0) a.len--;
}
int main()
{
cin>>sa;
l.len=l.num[1]=1;
n.len=r.len=strlen(sa);
for (int i=0;i<r.len;++i)
n.num[i+1]=r.num[i+1]=sa[r.len-i-1]-'0';
while (small(l,r))
{
for (int i=1;i<=mid.len;++i)
mid.num[i]=0;
mid.len=0;
Plus(l,r,mid);
div2(mid);
for (int i=1;i<=res.len;++i)
res.num[i]=0;
res.len=0;
mul(mid,mid,res);
if (small(res,n))
{
l.len=ans.len=mid.len;
for (int i=1;i<=ans.len;++i)
l.num[i]=ans.num[i]=mid.num[i];
add1(l);
}
else
{
r.len=mid.len;
for (int i=1;i<=mid.len;++i)
r.num[i]=mid.num[i];
dec1(r);
}
}
for (int i=ans.len;i;--i)
printf("%d",ans.num[i]);
return 0;
}