problem
高精度开根号
- 输入一个数
- 求平方根
solution
- 二分答案,如果mid*mid>原数就去找更小的,反之找更大的。
- 精度小于二忽略不计?
- 用到高精加,高精乘,加低精,除低精,比较大小这几个。
放弃调试,明天重写。
mmp
codes1(更快的AC版本
//二分答案
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int maxn = 1010;
int a[maxn], l[maxn], r[maxn], m[maxn], t[maxn];
//m=l+r>>1
void mid(){
//m = l;
memcpy(m,l,sizeof(l));
//m += r;
m[0] = r[0]+1;
for(int i = 1; i <= r[0]; i++){
m[i] += r[i];
if(m[i]>=10){
m[i] %= 10;
m[i+1]++;
}
}
while(m[0]>1 && m[m[0]]==0)m[0]--;
//m /= 2;
for(int i = m[0]; i >= 1; i--){
if(i > 1)m[i-1]+=m[i]%2*10;
m[i] /= 2;
}
while(m[0]>1 && m[m[0]]==0)m[0]--;
}
//return m*m>a;
bool C(){
//t = 0;
memset(t,0,sizeof(t));
//t = m*m;
for(int i = 1; i <= m[0]; i++)
for(int j = 1; j <= m[0]; j++)
t[i+j-1] += m[i]*m[j];
t[0] = m[0]*2;
for(int i = 1; i <= t[0]; i++){//处理进位
t[i+1] += t[i]/10;
t[i] %= 10;
}
while(t[0]>1 && t[t[0]]==0)t[0]--;
//return t>a;
if(t[0] != a[0])return t[0]>a[0];
for(int i = t[0]; i >= 1; i--)
if(t[i]!=a[i])return t[i]>a[i];
return 0;
}
int main(){
//输入
string s; cin>>s;
a[0] = s.size();
for(int i = 1; i <= a[0]; i++)a[i] = s[a[0]-i]-'0';
//二分
l[0] = 1;
r[0] = a[0]/2+2;
r[r[0]] = 1;
for(int i = 1; i <= 2000; i++){
mid(); //m=l+r>>1;
if(C())memcpy(r,m,sizeof(m));//r=m;
else memcpy(l,m,sizeof(m));//l=m;
}
//输出
for(int i = l[0]; i >= 1; i--)cout<<l[i];
return 0;
}
//二分答案
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int maxn = 1010;
int a[maxn], l[maxn], r[maxn], m[maxn], t[maxn];
//m=l+r>>1
void mid(){
//m = l;
memcpy(m,l,sizeof(l));
//m += r;
m[0] = r[0]+1;
for(int i = 1; i <= r[0]; i++){
m[i] += r[i];
if(m[i]>=10){
m[i] %= 10;
m[i+1]++;
}
}
while(m[0]>1 && m[m[0]]==0)m[0]--;
//m /= 2;
for(int i = m[0]; i >= 1; i--){
if(i > 1)m[i-1]+=m[i]%2*10;
m[i] /= 2;
}
while(m[0]>1 && m[m[0]]==0)m[0]--;
}
//return m*m>a;
bool C(){
//t = 0;
memset(t,0,sizeof(t));
//t = m*m;
for(int i = 1; i <= m[0]; i++)
for(int j = 1; j <= m[0]; j++)
t[i+j-1] += m[i]*m[j];
t[0] = m[0]*2;
for(int i = 1; i <= t[0]; i++){//处理进位
t[i+1] += t[i]/10;
t[i] %= 10;
}
while(t[0]>1 && t[t[0]]==0)t[0]--;
//return t>a;
if(t[0] != a[0])return t[0]>a[0];
for(int i = t[0]; i >= 1; i--)
if(t[i]!=a[i])return t[i]>a[i];
return 0;
}
int main(){
//输入
string s; cin>>s;
a[0] = s.size();
for(int i = 1; i <= a[0]; i++)a[i] = s[a[0]-i]-'0';
//二分
l[0] = 1;
r[0] = a[0]/2+2;
r[r[0]] = 1;
for(int i = 1; i <= 2000; i++){
mid(); //m=l+r>>1;
if(C())memcpy(r,m,sizeof(m));//r=m;
else memcpy(l,m,sizeof(m));//l=m;
}
//输出
for(int i = l[0]; i >= 1; i--)cout<<l[i];
return 0;
}
code2(更容易读懂被TLE一个点的版本
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int maxn = 2010;
struct Bigint{ int len, num[maxn]; };
//return a+b;
Bigint add(Bigint a, Bigint b){
Bigint ans; memset(ans.num,0,sizeof(ans.num));
ans.len = max(a.len,b.len)+1;
for(int i = 1; i <= ans.len; i++){
ans.num[i] += a.num[i]+b.num[i];
ans.num[i+1] += ans.num[i]/10;
ans.num[i] %= 10;
}
while(ans.len>1 && ans.num[ans.len]==0)ans.len--;
return ans;
}
//return (a+b)/2;
Bigint avg(Bigint a, Bigint b){
Bigint ans; memset(ans.num,0,sizeof(ans.num));
ans = add(a,b);
//copy from
for(int i=ans.len;i>=2;i--){
ans.num[i-1]+=( ans.num[i]%2)*10;
ans.num[i]/=2;
}
ans.num[1] /= 2;
if(ans.num[ans.len]==0)ans.len--;
return ans;
}
//return a+2;
Bigint plustwo(Bigint x){
x.num[1] += 2;
for(int i = 1; i <= x.len; i++){
x.num[i+1] += x.num[i]/10;
x.num[i] %= 10;
}
if(x.num[x.len+1]>0)x.len++;
return x;
}
//return a*b;
Bigint times(Bigint a, Bigint b){
Bigint ans; memset(ans.num,0,sizeof(ans.num));
ans.len = a.len+b.len+1;
for(int i = 1; i <= a.len; i++)
for(int j = 1; j <= b.len; j++)
ans.num[i+j-1] += a.num[i]*b.num[j];
for(int i = 1; i <= ans.len; i++){
ans.num[i+1] += ans.num[i]/10;
ans.num[i] %= 10;
}
while(ans.len>1 && ans.num[ans.len]==0)ans.len--;
return ans;
}
//return a<=b;
bool over(Bigint a, Bigint b){
if(a.len != b.len)return a.len < b.len;
for(int i = a.len; i >= 1; i--)
if(a.num[i] != b.num[i])return a.num[i]<b.num[i];
return true;
}
Bigint l, r, mid, tmp;
int main(){
ios::sync_with_stdio(false);
string s; cin>>s;
tmp.len = s.size();
for(int i = 1; i <= tmp.len; i++)
tmp.num[i] += s[tmp.len-i]-'0';
l.len = 1, l.num[1] = 3; r = tmp;
do{
mid = avg(l,r);
if(!over(times(mid,mid),tmp))r = mid;
else l = mid;
}while(over(plustwo(l),r)); //l+2<=r;
/*
for(int i = 1; i <= 1500; i++){
mid = avg(l,r);
if(!over(times(mid,mid),tmp))r = mid;
else l = mid;
}
*/
for(int i = l.len; i >= 1; i--)
cout<<l.num[i];
/*
mid = times(l,r);
for(int i = mid.len; i >= 1; i--)
cout<<mid.num[i]; cout<<'\n';
*/
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int maxn = 2010;
struct Bigint{ int len, num[maxn]; };
//return a+b;
Bigint add(Bigint a, Bigint b){
Bigint ans; memset(ans.num,0,sizeof(ans.num));
ans.len = max(a.len,b.len)+1;
for(int i = 1; i <= ans.len; i++){
ans.num[i] += a.num[i]+b.num[i];
ans.num[i+1] += ans.num[i]/10;
ans.num[i] %= 10;
}
while(ans.len>1 && ans.num[ans.len]==0)ans.len--;
return ans;
}
//return (a+b)/2;
Bigint avg(Bigint a, Bigint b){
Bigint ans; memset(ans.num,0,sizeof(ans.num));
ans = add(a,b);
//copy from
for(int i=ans.len;i>=2;i--){
ans.num[i-1]+=( ans.num[i]%2)*10;
ans.num[i]/=2;
}
ans.num[1] /= 2;
if(ans.num[ans.len]==0)ans.len--;
return ans;
}
//return a+2;
Bigint plustwo(Bigint x){
x.num[1] += 2;
for(int i = 1; i <= x.len; i++){
x.num[i+1] += x.num[i]/10;
x.num[i] %= 10;
}
if(x.num[x.len+1]>0)x.len++;
return x;
}
//return a*b;
Bigint times(Bigint a, Bigint b){
Bigint ans; memset(ans.num,0,sizeof(ans.num));
ans.len = a.len+b.len+1;
for(int i = 1; i <= a.len; i++)
for(int j = 1; j <= b.len; j++)
ans.num[i+j-1] += a.num[i]*b.num[j];
for(int i = 1; i <= ans.len; i++){
ans.num[i+1] += ans.num[i]/10;
ans.num[i] %= 10;
}
while(ans.len>1 && ans.num[ans.len]==0)ans.len--;
return ans;
}
//return a<=b;
bool over(Bigint a, Bigint b){
if(a.len != b.len)return a.len < b.len;
for(int i = a.len; i >= 1; i--)
if(a.num[i] != b.num[i])return a.num[i]<b.num[i];
return true;
}
Bigint l, r, mid, tmp;
int main(){
ios::sync_with_stdio(false);
string s; cin>>s;
tmp.len = s.size();
for(int i = 1; i <= tmp.len; i++)
tmp.num[i] += s[tmp.len-i]-'0';
l.len = 1, l.num[1] = 3; r = tmp;
do{
mid = avg(l,r);
if(!over(times(mid,mid),tmp))r = mid;
else l = mid;
}while(over(plustwo(l),r)); //l+2<=r;
/*
for(int i = 1; i <= 1500; i++){
mid = avg(l,r);
if(!over(times(mid,mid),tmp))r = mid;
else l = mid;
}
*/
for(int i = l.len; i >= 1; i--)
cout<<l.num[i];
/*
mid = times(l,r);
for(int i = mid.len; i >= 1; i--)
cout<<mid.num[i]; cout<<'\n';
*/
return 0;
}