一道~~神仙~~高精度压位板子题

同步:http://buringstraw.win/index.php/archives/20/

一道神仙高精度压位板子题

题目

出自1.28的考试

高精度开平方【水】

描述

如题目所属

輸入

一个整数 N。

輸出

N 的平方根下取整。

輸入範例 1
1
輸出範例 1
1
提示

对于 100%的数据,0<N<=10^1000。

分析

首先看标题里的一个大大的水我就知道这是一道水题事情不简单

慢速打了一个普通的高精度。

后来发现每个点都有1000位。。。。

所以需要压位,当然,开始我是不会的。两天后的今天我终于写了出来!

代码(板子)

#include<bits/stdc++.h>
#define LL long long
#define max(a,b) ((a)>(b))?(a):(b)
#define min(a,b) ((a)<(b))?(a):(b)
#define p 8//要压的位数 
#define carry 100000000//相应的10的P次方 用于进位 
using namespace std;

const LL MAXN=3005;
const string scarry="100000000";

struct bigNum{
    private:
        LL t[MAXN],siz;
    
    public:
        bigNum(string s){
            memset(t,0,sizeof(t));
            siz=0;
            LL len=s.size();
            string tmp;
            tmp.resize(p);
            while(len>=p){
                for(LL i=0;i<p;++i){
                    tmp[i]=s[len-p+i];
                }
                ++siz;
                for(LL i=0;i<tmp.size();++i){
                    t[siz]+=tmp[i]-'0';
                    if(i<tmp.size()-1){
                        t[siz]*=10;
                    }
                }
                len-=p;
            }
            if(len){
                tmp="";
                tmp.resize(len);
                for(LL i=0;i<len;++i){
                    tmp[i]=s[i];
                }
                ++siz;
                for(LL i=0;i<tmp.size();++i){
                    t[siz]+=tmp[i]-'0';
                    if(i<tmp.size()-1){
                        t[siz]*=10;
                    }
                }
            }       
        }
        
        bigNum(void){
            memset(t,0,sizeof(t));
            siz=1;
            return;
        }
        
        bigNum(LL x){
            memset(t,0,sizeof(t));
            char tmp[3005];
            siz=0;
            while(x){
                tmp[++siz]=x%10+'0';
                x/=10;
            }
            
            *this=(string)tmp;
            return;
        }
        
        void print(void){
            printf("%d",t[siz]);
            for(LL i=siz-1;i>=1;--i){
                char tmp[]="%00d";
                tmp[2]=p+'0';
                printf(tmp,t[i]);
            }
            putchar('\n');
        }
        
        LL size(void){
            return siz;
        }
        
        friend bigNum operator -(bigNum a,bigNum b){
            if(a==b)return (bigNum)0;
            if(a<b)swap(a,b);
            bigNum c;
            LL jw=0;
            LL len=max(a.size(),b.size());
            for(LL i=1;i<=len;++i){
                c.t[i]=a.t[i]-b.t[i]-jw;
                if(c.t[i]<0){
                    jw=1;
                    c.t[i]+=carry;
                }
                else jw=0;
            }
            while(c.t[len]==0){
                --len;
            }
            c.siz=len;
            return c;
        }
        
        friend bigNum operator +(bigNum a,bigNum b){
            bigNum c;
            LL jw=0;
            LL len=max(a.size(),b.size());
            for(LL i=1;i<=len;++i){
                c.t[i]=a.t[i]+b.t[i]+jw;
                if(c.t[i]>=carry){
                    jw=1;
                    c.t[i]-=carry;
                }
                else jw=0;
            }
            if(jw){
                c.t[++len]=1;
            }
            c.siz=len;
            return c;
        }
        
        friend bigNum operator*(bigNum a,bigNum b){
            bigNum c;
            LL len=a.siz+b.siz;
            for(LL i=1;i<=a.siz;i++){
                for(LL j=1;j<=b.siz;j++){
                    c.t[i+j-1]+=a.t[i]*b.t[j];
                    c.t[i+j]+=c.t[i+j-1]/carry;
                    c.t[i+j-1]%=carry;
                }
            }
            while(len>0 && c.t[len]==0)len--;
            c.siz=len;
            return c;
        }
        
        friend bigNum operator/(bigNum a,int b)
        {
            bigNum c;
            LL g=0;
            for(int i=a.siz;i>0;--i){
                g=g*carry+a.t[i];
                c.t[i]=g/b;
                g%=b;
            }
            c.siz=a.siz;
            while(c.siz>1&&c.t[c.siz]==0)c.siz--;
            return c;
        }
        
        friend bool operator ==(bigNum a,bigNum b){
            if(a.siz!=b.siz){
                return 0;
            }
            for(LL i=1;i<=a.siz;++i){
                if(a.t[i]!=b.t[i]){
                    return 0;
                }
            }
            return 1;
        }
        
        friend bool operator <(bigNum a,bigNum b){
            if(a.siz!=b.siz){
                return a.siz<b.siz;
            }
            for(LL i=a.siz;i>=1;--i){
                if(a.t[i]<b.t[i]){
                    return 1;
                }
                if(a.t[i]>b.t[i]){
                    return 0;
                }
            }
            return 0;
        }
        
        friend bool operator <=(bigNum a,bigNum b){
            return !(a>b);
        }
        
        friend bool operator >(bigNum a,bigNum b){
            if(a.siz!=b.siz){
                return a.size()>b.size();
            }
            for(LL i=a.size();i>=1;--i){
                if(a.t[i]>b.t[i]){
                    return 1;
                }
                if(a.t[i]<b.t[i]){
                    return 0;
                }
            }
            return 0;
        }
    
        friend bool operator >=(bigNum a,bigNum b){
            return !(a<b);
        }
};

int main(void){
    string s;
    cin>>s;
    bigNum n(s);
    bigNum l(1),r=n,mid,ans,yi("1");
    while(l<=r){
        mid=(l+r)/2;
        if((mid*mid)>n){
            r=mid-yi;
        }
        else{
            ans=mid;
            l=mid+yi;
        }
    }
    ans.print();
    return 0;
}

居然有两百多行。

功能全面(bushi),除了没有高精度÷高精度。。。

写出来之后一直WA,对拍都拍不出问题。。。

结果发现是交错题了(捂脸)

TIM截图20190130144759.png

猜你喜欢

转载自www.cnblogs.com/buringstraw/p/10338284.html
今日推荐