【codevs3119】高精度开根号(二分答案)

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;
}

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;
}
阅读更多

没有更多推荐了,返回首页