【学校OJ】 二分答案+高精度 高精度开平方

题目描述

输入

一个整数 N。 

输出

N 的平方根下取整。 

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

123456789012345678901234567890

样例输出

351364182882014

提示

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

    诈尸啦!诈尸啦!诈尸啦!重要的事情说三遍!

    我看到这题目描述也是醉了……这语言描述过于简单了吧……心中自是呕吐着……

    一看这规模,拿起重载运算符开始写了……泪奔中——这道题思路很好想,高精度二分答案,最低0,最高N,平一下方,尝试是否有可能,然后减少区间,It's so easy好吧,还是要乖乖的写会儿+ - * / ^ > <等一系列猥琐的运算符……重载运算符三天后,我终于写完了代码!用‘|’表示开根,真佩服我自己!

    凝结着吐出的鲜血的代码新鲜出炉:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct Big
{
	int A[5005];
	int len;
	int f;
	Big()
	{
		memset(A,0,sizeof(A));
		len=1;
		f=0;
	}
	void print()
	{
		if(f)
			printf("-");
		for(int i=len;i>=1;i--)
			printf("%d",A[i]);
	}
	void read()
	{
		char _s[5005];
		scanf("%s",_s);
		len=strlen(_s);
		int k=0;
		if(_s[0]=='-')
		{
			f=1;
			len--;
			k++;
		}
		for(int i=1+k;i<=len+k;i++)
			A[i-k]=_s[len-i+2*k]-'0';
		while(!A[len]&&len>1)
			len--;
		if(len==1&&!A[1])
			f=0;
	}
	bool operator >(Big c)const
	{
		if(len>c.len)
			return 1;
		if(len<c.len)
			return 0;
		for(int i=len;i>=1;i--)
		{
			if(A[i]>c.A[i])
				return 1;
			if(A[i]<c.A[i])
				return 0;
		}
		return 0;
	}
	bool operator <(Big c)const
	{
		if(len<c.len)
			return 1;
		if(len>c.len)
			return 0;
		for(int i=len;i>=1;i--)
		{
			if(A[i]<c.A[i])
				return 1;
			if(A[i]>c.A[i])
				return 0;
		}
		return 0;
	}
	bool operator >=(Big c)const{Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;return !(a<c);}
	bool operator <=(Big c)const{Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;return !(a>c);}
	bool operator ==(Big c)const{Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;return !(a>c)&&!(a<c);}
	bool operator !=(Big c)const{Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;return !(a==c);}
	Big operator +(Big c)
	{
		Big g;
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;
		g.len=max(len,c.len)+1;
		if(f==c.f)
			g.f=f;
		else
			if(f==1)
			{
				g=a;
				g.f=0;
				g=c-g;
				return g;
			}
			else
			{
				g=c;
				g.f=0;
				g=a-g;
				return g;
			}
		for(int i=1;i<=g.len;i++)
		{
			g.A[i]+=A[i]+c.A[i];
			g.A[i+1]+=g.A[i]/10;
			g.A[i]%=10;
		}
		if(!g.A[g.len])
			g.len--;
			
		if(g.len==1&&!g.A[1])
			g.f=0;
		return g;
	}
	Big operator -(Big c)
	{
		Big g;
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;
		if(f==c.f)
			g.f=f;
		else
			if(f==1)
			{
				g=c;
				g.f=1;
				g=g+a;
				return g;
			}
			else
			{
				g=c;
				g.f=0;
				g=a+g;
				return g;
			}
		if(a>=c)
		{
			g.len=len;
			for(int i=1;i<=len;i++)
			{
				g.A[i]+=A[i]-c.A[i];
				if(g.A[i]<0)
				{
					g.A[i]+=10;
					g.A[i+1]--;
				}
			}
			for(int i=len;i>=2;i--)
			{
				if(g.A[i])
					break;
				g.len--;
			}
		}
		else
		{
			g.len=c.len;
			for(int i=1;i<=c.len;i++)
			{
				g.A[i]+=c.A[i]-A[i];
				if(g.A[i]<0)
				{
					g.A[i]+=10;
					g.A[i+1]--;
				}
			}
			for(int i=len;i>=2;i--)
			{
				if(g.A[i])
					break;
				g.len--;
			}
			g.f=!g.f;
		}
		return g;
	}
	Big operator *(Big c)const
	{
		Big g;
		if((len==1&&!A[len])||(c.len==1&&!c.A[c.len]))
			return g;
		if(f!=c.f)
			g.f=1;
		for(int i=1;i<=len;i++)
		{
			for(int j=1;j<=c.len;j++)
			{
				g.A[i+j-1]+=A[i]*c.A[j];
				if(g.A[i+j-1]>=10)
				{
					g.A[i+j]+=g.A[i+j-1]/10;
					g.A[i+j-1]%=10;
				}
			}
		}
		g.len=len+c.len;
		if(!g.A[len+c.len])
			g.len--;
		return g;
	}
	Big operator /(Big c)const
	{
		Big a;memcpy(a.A,c.A,sizeof(c.A));a.len=c.len;
		Big ten;ten.len=2;ten.A[2]=1;
		Big one;one.A[1]=1;
		Big zero;
		if(c.len==1&&c.A[1]==0)
			return zero;
		Big g;
		for(int i=len;i>=1;i--)
		{
			zero=zero*ten;
			zero.A[1]=A[i];
			while(zero>=a)
			{
				zero=zero-a;
				Big t=ten^(i-1);
				g=g+t;
			}
		}
		Big O;
		if(g.len==1&&!g.A[1])
			return O;
		g.f=f==c.f?0:1;
		return g;
	}
	Big operator %(Big c)const
	{
		Big a;memcpy(a.A,c.A,sizeof(c.A));a.len=c.len;a.f=f;
		Big ten;ten.len=2;ten.A[2]=1;
		Big one;one.A[1]=1;
		Big zero;
		if(c.len==1&&c.A[1]==0)
			return zero;
		for(int i=len;i>=1;i--)
		{
			zero=zero*ten;
			zero.A[1]=A[i];
			while(zero>=a)
				zero=zero-a;
		}
		return zero;
	}
	Big operator ^(int k)const
	{
		Big op;
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;
		op.A[1]=1;
		if(k==0)
			return op;
		Big pi=(a^(k/2));
		op=pi*pi;
		if(k%2)
			op=op*a;
		return op;
	}
	Big operator |(int k) const
	{
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;
		Big two;two.A[1]=2;
		Big one;one.A[1]=1;
		Big l;
		Big r=a;
		Big m;
		for(;l<r;)
		{
			m=(l+r+one)/two;
			if((m^k)>a)
				r=m-one;
			else
				l=m;
		}
		return l;
	}
}num,num2;
int main()
{
	num.read();
	num2=num|2;
	num2.print();
}

    有没有被惊艳到?我就是喜欢写高精度!加减乘除方根一定要考虑负数,能写高精弄高精就不写高精弄低精(不然怎么会用了三天),自信满满地提交上去——TLE,好吧我知错了QAQ,看来不要想太多啊……除法就除以一个2写成高精度当然耗时啊……算了,写简单点吧……顺便压个位(超时肯定有位数的缘故——1000位不超才怪嘞)。int压4位——超时,int压5位——溢出,long long压5位——超时……历经无数次尝试,我盖起了一座鲜红的大楼……╮(╯▽╰)╭,最后,终于long long压8位过了!

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
struct Big
{
	long long A[5005];
	int len;
	int f;
	Big()
	{
		memset(A,0,sizeof(A));
		len=1;
		f=0;
	}
	void print()//
	{
		printf("%lld",A[len]);
		for(int i=len-1;i>=1;i--)
			printf("%08lld",A[i]);
	}
	void read()//
	{
		char _s[5005];
		scanf("%s",_s);
		len=(strlen(_s)+7)/8;
		int slen=strlen(_s);
		for(int i=1;i<=slen;i++)
		{
			int o=slen-i,p=(i+7)/8;
			A[p]+=(_s[o]-'0')*pow(10,(i-1)%8);
		}
	}
	bool operator <(Big c)const
	{
		if(len<c.len)
			return 1;
		if(len>c.len)
			return 0;
		for(int i=len;i>=1;i--)
		{
			if(A[i]<c.A[i])
				return 1;
			if(A[i]>c.A[i])
				return 0;
		}
		return 0;
	}
	Big operator +(Big c)const//
	{
		Big g;
		g.len=max(len,c.len)+1;
		for(int i=1;i<=g.len;i++)
		{
			g.A[i]+=A[i]+c.A[i];
			g.A[i+1]+=g.A[i]/100000000;
			g.A[i]%=100000000;
		}
		if(!g.A[g.len])
			g.len--;
		return g;
	}
	Big operator -(Big c)const//
	{
		Big g;
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;
		g.len=len;
		for(int i=1;i<=len;i++)
		{
			g.A[i]+=A[i]-c.A[i];
			if(g.A[i]<0)
			{
				g.A[i]+=100000000;
				g.A[i+1]-=1;
			}
		}
		for(int i=len;i>=2;i--)
		{
			if(g.A[i])
				break;
			g.len--;
		}
		return g;
	}
	Big operator *(Big c)const//
	{
		Big g;
		if((len==1&&!A[len])||(c.len==1&&!c.A[c.len]))
			return g;
		for(int i=1;i<=len;i++)
		{
			for(int j=1;j<=c.len;j++)
			{
				g.A[i+j-1]+=A[i]*c.A[j];
				if(g.A[i+j-1]>=100000000)
				{
					g.A[i+j]+=g.A[i+j-1]/100000000;
					g.A[i+j-1]%=100000000;
				}
			}
		}
		g.len=len+c.len;
		if(!g.A[len+c.len])
			g.len--;
		return g;
	}
	Big operator /(int k)const//
	{
		Big g;
		int sum=0;
		for(int i=len;i>=1;i--)
		{
			sum*=100000000;
			sum+=A[i];
			int o=sum/k;
			if(o)
				g.len=max(i,g.len);
			g.A[i]=o;
			sum%=k;
		}
		return g;
	}
	Big operator ^(int k)const
	{
		Big op;
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;a.f=f;
		op.A[1]=1;
		if(k==0)
			return op;
		Big pi=(a^(k/2));
		op=pi*pi;
		if(k%2)
			op=op*a;
		return op;
	}
	Big operator |(int k)const
	{
		Big a;memcpy(a.A,A,sizeof(A));a.len=len;
		Big one;one.A[1]=1;
		Big l;
		Big r=a;
		Big m;
		for(;l<r;)
		{
			m=(l+r+one)/2;
			if(a<(m^k))
				r=m-one;
			else
				l=m;
		}
		return l;
	}
}num,num2,num3;
int p;
int main()
{
	num.read();
	(num|2).print();
}
    鲜血的教训啊~~~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值