题目链接

https://www.dotcpp.com/oj/problem1450.html

解题思路

不知道你有没有想到一道题https://www.dotcpp.com/oj/problem1492.html
异曲同工
大佬讲解思路
这位大佬讲针不戳!!
可以看看大佬的思路,看看我讲的代码!
揪出本质,是在考察如何实现高精度开二次根。
那我们就来絮叨絮叨开二次方根的代码理解。
核心代码三部分:

//高精度乘法
//正常的高精度乘法的板子
string large_mul(string ts1,string ts2){
    string res;
    int a[N],b[N],c[N];
    memset(a,0,sizeof a);//没有直接error!!! 
    memset(b,0,sizeof b);//没有直接error!!!
    memset(c,0,sizeof c);//没有直接error!!!    
    int len1=ts1.length();
    int len2=ts2.length();
    //逆置
    for(int i=0;i<len1;i++)
        a[len1-i-1]=ts1[i]-'0';
    for(int i=0;i<len2;i++)
        b[len2-i-1]=ts2[i]-'0';
    //乘法核心代码
    for(int i=0;i<len1;i++)    
        for(int j=0;j<len2;j++){
            c[i+j]+=a[i]*b[j];
            c[i+j+1]+=c[i+j]/10;
            c[i+j]%=10;
        }
    int len=len1+len2-1;
    if(c[len]!=0) len++;
    //逆置并转换成字符串
    for(int i=len-1;i>=0;i--)
        res+=c[i]+'0';

    return res;
}

//高精度开根(!!!重点!!!)
string large_sqrt(string a){
    string res;
    int len=a.length();
    int tlen=len/2;
    if(len&1){//奇数 
        for(int i=0;i<tlen+1;i++){
            for(int j=0;j<=9;j++){
                string tmpstr=res;
                tmpstr+=j+'0';
                if(large_cmp(large_mul(tmpstr,tmpstr),a,2*(tlen-i))){//大于了要被开根的数,则让res拼接上前一个j//cmp的参数下面讲解
                    res+=j-1+'0';
                    break;
                }
                if(j==9) res+='9';//前面一直没找到大于被开根的数,拼接上9
            }
        }
    }
    else{
        for(int i=0;i<tlen;i++){
            for(int j=0;j<=9;j++){
                string tmpstr=res;
                tmpstr+=j+'0';
                if(large_cmp(large_mul(tmpstr,tmpstr),a,2*(tlen-1-i))){
                    res+=j-1+'0';
                    break;
                }
                if(j==9) res+='9';
            }
        }
    }
    return res;
}

//高精度比较(!!!重点!!!)
bool large_cmp(string a,string b,int rest){//a是我们尝试去相乘的两个数的积,b是被开根数,rest是a剩下的几位,剩下的几位暂时为0
    int alen=a.length();
    int blen=b.length();
    if(blen<alen+rest) return true;//算出的两数积长度大于被开根数
    if(blen>alen+rest) return false;//算出的两数积长度小于被开根数
    for(int i=0;i<blen;i++){
        if(a[i]-'0'>b[i]-'0') return true;//同一位置,a的数大
        if(a[i]-'0'<b[i]-'0') return false;//同一位置,a的数小
    }
    return false;//如果完全相同,返回假,,因为我们上面比较判断之后res拼接的是j的前一个数
}

//至此,难点和核心都讲完了,确实挺难一下理解透彻的

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=1010;

string large_mul(string ts1,string ts2){
    string res;
    int a[N],b[N],c[N];
    memset(a,0,sizeof a);//没有直接error!!! 
    memset(b,0,sizeof b);//没有直接error!!!
    memset(c,0,sizeof c);//没有直接error!!!    
    int len1=ts1.length();
    int len2=ts2.length();

    for(int i=0;i<len1;i++)
        a[len1-i-1]=ts1[i]-'0';
    for(int i=0;i<len2;i++)
        b[len2-i-1]=ts2[i]-'0';

    for(int i=0;i<len1;i++)    
        for(int j=0;j<len2;j++){
            c[i+j]+=a[i]*b[j];
            c[i+j+1]+=c[i+j]/10;
            c[i+j]%=10;
        }
    int len=len1+len2-1;
    if(c[len]!=0) len++;

    for(int i=len-1;i>=0;i--)
        res+=c[i]+'0';

    return res;
}

bool large_cmp(string a,string b,int rest){
    int alen=a.length();
    int blen=b.length();
    if(blen<alen+rest) return true;
    if(blen>alen+rest) return false;
    for(int i=0;i<blen;i++){
        if(a[i]-'0'>b[i]-'0') return true;
        if(a[i]-'0'<b[i]-'0') return false;
    }
    return false;
}

string large_sqrt(string a){
    string res;
    int len=a.length();
    int tlen=len/2;
    if(len&1){//奇数 
        for(int i=0;i<tlen+1;i++){
            for(int j=0;j<=9;j++){
                string tmpstr=res;
                tmpstr+=j+'0';
                if(large_cmp(large_mul(tmpstr,tmpstr),a,2*(tlen-i))){
                    res+=j-1+'0';
                    break;
                }
                if(j==9) res+='9';
            }
        }
    }
    else{
        for(int i=0;i<tlen;i++){
            for(int j=0;j<=9;j++){
                string tmpstr=res;
                tmpstr+=j+'0';
                if(large_cmp(large_mul(tmpstr,tmpstr),a,2*(tlen-1-i))){
                    res+=j-1+'0';
                    break;
                }
                if(j==9) res+='9';
            }
        }
    }
    return res;
}

int main(){
    string s1,s2;
    cin>>s1>>s2;

    cout<<large_mul(large_sqrt(s1),large_sqrt(s2));
} 

总结

理解了一下午+半晚上,多温习才能记熟!