[code3119]高精度练习之大整数开根
试题描述
|
给出一个正整数n,求n开根号后的整数部分的值。n的位数不超过1000位。
|
输入
|
读入一个不超过1000位的正整数n。
|
输出
|
输出所求答案
|
输入示例
|
17
|
输出示例
|
4
|
高精度开根:需要用的是手算开平方根的方法,我其实这个方法也不会,是临时到网上学习的
网上说的方法都挺详细的,我在这里就不详细说了,下面直接贴代码:
高精度模板需要用到高减高,高乘低,高加低。
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<queue> 6 #include<cstdio> 7 using namespace std; 8 typedef long long LL; 9 inline int read() 10 { 11 int x=0,f=1;char c=getchar(); 12 while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} 13 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 14 return x*f; 15 } 16 const int maxn=1010; 17 struct data 18 { 19 int l,v[maxn]; 20 data(){l=1;memset(v,0,sizeof(v));} 21 data operator = (const data& s) 22 { 23 l=s.l;memset(v,0,sizeof(v)); 24 for(int i=1;i<=l;i++)v[i]=s.v[i]; 25 return *this; 26 } 27 data operator = (const int& s) 28 { 29 l=1;v[1]=s; 30 while(v[l]>9)v[l+1]+=v[l]/10,v[l]%=10,l++; 31 return *this; 32 } 33 data operator - (const data& s) 34 { 35 data c;c.l=l; 36 for(int i=1;i<=c.l;i++)c.v[i]=v[i]; 37 for(int i=1;i<=c.l;i++)c.v[i]-=s.v[i]; 38 for(int i=1;i<c.l;i++)if(c.v[i]<0)c.v[i]+=10,c.v[i+1]--; 39 while(!c.v[c.l])c.l--; 40 return c; 41 } 42 data operator * (const int& s) 43 { 44 data c;c.l=l; 45 for(int i=1;i<=c.l;i++)c.v[i]=v[i]*s; 46 for(int i=1;i<c.l;i++)if(c.v[i]>9)c.v[i+1]+=(c.v[i])/10,c.v[i]%=10; 47 while(c.v[c.l]>9)c.v[c.l+1]+=(c.v[c.l])/10,c.v[c.l]%=10,c.l++; 48 return c; 49 } 50 data operator + (const int& s) 51 { 52 data c=*this; 53 c.v[1]+=s;int i=1; 54 while(c.v[i]>9)c.v[i+1]+=c.v[i]/10,c.v[i]%=10,i++; 55 c.l=max(c.l,i); 56 return c; 57 } 58 bool operator <= (const data& t)const 59 { 60 if(l!=t.l)return l<t.l; 61 for(int i=l;i;i--)if(v[i]!=t.v[i])return v[i]<t.v[i]; 62 return 1; 63 } 64 }a; 65 int num[510]; 66 void scan(data &s) 67 { 68 char ch[maxn]; 69 scanf("%s",ch+1);s.l=strlen(ch+1); 70 for(int i=1;i<=s.l;i++)s.v[i]=ch[s.l-i+1]-'0'; 71 return; 72 } 73 void print(data s){for(int i=s.l;i;i--)printf("%d",s.v[i]);cout<<endl;} 74 void init(data s)//将这个数从个位起,向左每两位分一节(例如65536变成6,55,36) 75 { 76 if(s.l%2) 77 { 78 num[0]=s.v[s.l]; 79 for(int i=2;i<=s.l;i+=2)num[i/2]=s.v[s.l-i+1]*10+s.v[s.l-i]; 80 } 81 else for(int i=1;i<=s.l;i+=2)num[i/2]=s.v[s.l-i+1]*10+s.v[s.l-i]; 82 return; 83 } 84 data Sqrt(data s) 85 { 86 data ans,t,q,p; 87 ans=0;t=0; 88 int len= s.l%2 ? s.l/2+1 : s.l/2;//划分块的数量 89 for(int i=0;i<len;i++) 90 { 91 t=(t*100)+num[i]; 92 p=ans*20;ans=ans*10;//这里的ans要提前乘以10,如果下面的循环一次都没进去的话,ans就不会更新了 93 for(int j=9;j>=0;j--) 94 { 95 q=(p+j)*j; 96 if(q<=t) 97 { 98 ans=ans+j; 99 t=t-q; 100 break; 101 } 102 } 103 } 104 return ans; 105 } 106 int main() 107 { 108 scan(a); 109 init(a); 110 print(Sqrt(a)); 111 return 0; 112 }