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


    同步: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('
    ');
    		}
    		
    		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

  • 相关阅读:
    雅礼集训2017day5乱写
    任意值域最长公共子序列问题
    雅礼集训2017day4乱写
    雅礼集训2017day2乱写
    SP839
    雅礼集训2017day1乱写
    CF671E
    仅维护当前区间影响类问题的线段树
    「雅礼集训 2017 Day4」编码
    Codeforces Round #503 Div. 2
  • 原文地址:https://www.cnblogs.com/buringstraw/p/10338284.html
Copyright © 2020-2023  润新知