bzoj 1213 //1213: [HNOI2004]高精度开根 //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1213
更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录
https://www.luogu.org/problemnew/solution/P2293
//1213: [HNOI2004]高精度开根
//在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1213
//以高精度算法经验,预感此题会超越100行代码
//估计8位压位是少不了了。考虑相乘,数据可能会溢出,采用4位压位。
//估计需编写,比较大小的函数,高精度乘高精度,高精度除低精度,高精度加高精度。
//编写高精度算法,很重要的一条,每编写一个函数都要测试一遍。
//样例通过,bzoj里提交,
//Runtime_Error 1016 kb 16 ms C++/Edit 2384 B 2019-11-5
//在https://www.luogu.org/problem/P2293提交20分。20分代码如下,尽力了。
#include <stdio.h>
#include <string.h>
#define BASE 10000
#define BIT 4
#define maxn 10020
int a[maxn/BIT],b[maxn/BIT],c[maxn/BIT],m,left[maxn],right[maxn],mid[maxn],left1[maxn],one[10];
char s[maxn];
int cmp(int *x,int *y){//x>y 1;x<y -1;x==y 0
int i;
if(x[0]>y[0])return 1;
if(x[0]<y[0])return -1;
for(i=x[0];i>=1;i--)
if(x[i]>y[i])return 1;
else if(x[i]<y[i])return -1;
return 0;
}
void read(int *x){//读取,需要多编多练
int len,i,tmp;
char c;
scanf("%s",s+1);
len=strlen(s+1);
for(i=1;i<=len/2;i++)c=s[i],s[i]=s[len-i+1],s[len-i+1]=c;//逆序
x[0]=(len-1)/BIT+1;
for(i=1;i<=len;i++){//123456789
if((i-1)%BIT==0)x[(i-1)/BIT+1]=0,tmp=1;
x[(i-1)/BIT+1]+=(s[i]-'0')*tmp;
tmp*=10;
}
}
void print(int *x){
int i;
printf("%d",x[x[0]]);
for(i=x[0]-1;i>=1;i--)printf("%04d",x[i]);
}
void div(int *x,int *y){//y=x/2
int i;
x[x[0]+1]=0;
for(i=x[0];i>=1;i--)y[i]=(x[i+1]%2*BASE+x[i])/2;
i=x[0];
while(i&&!y[i])i--;//保证最后结果i>=1
y[0]=i;
}
void add(int *x,int *y,int *z){//z=x+y
int i;
z[0]=x[0]>y[0]?x[0]:y[0];
for(i=1;i<=z[0];i++){
z[i]+=x[i]+y[i];//此处错写成z[i]=x[i]+y[i];
z[i+1]=z[i]/BASE;//此处错写成z[i+1]+=z[i]/BASE;
z[i]%=BASE;//此处错写成z[i]/=BASE;
}
if(z[i])z[0]=i;
}
void mul(int *x,int *y,int *z){//z=x*y
int i,j;
z[0]=x[0]+y[0];
for(i=1;i<=x[0];i++)
for(j=1;j<=y[0];j++){
z[i+j-1]+=x[i]*y[j];
z[i+j-1+1]+=z[i+j-1]/BASE;//此处错写成z[i+j-1+1]=z[i+j-1]/BASE;
z[i+j-1]%=BASE;
}
i=z[0];
while(i&&!z[i])i--;
z[0]=i;
}
int judge(int *x){
int f[maxn/BIT],g[maxn/BIT],i;
memset(f,0,sizeof(f)),f[0]=1,f[1]=1;
for(i=1;i<=m;i++){
memset(g,0,sizeof(g));
mul(x,f,g);
memcpy(f,g,sizeof(g));
}
if(cmp(g,a)>=0)return 1;
else return 0;
}
int main(){
scanf("%d",&m);
read(a),left[0]=1,left[1]=0,memcpy(right,a,sizeof(a)),one[0]=1,one[1]=1;
while(cmp(left1,right)==-1){//left+1<right
memset(b,0,sizeof(b));
add(left,right,b);
div(b,mid);
if(judge(mid))memcpy(right,mid,sizeof(mid));
else memcpy(left,mid,sizeof(mid));
memset(left1,0,sizeof(left1));
add(left,one,left1);
}
print(right);
}
//此文https://www.cnblogs.com/lxyyyy/p/10889765.html代码,与本人比较接近,进行对照研究,