一道~~神仙~~高精度压位板子题
同步:https://zhufn.fun/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,对拍都拍不出问题。。。
结果发现是交错题了(捂脸)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?