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

bzoj 1213 //1213: [HNOI2004]高精度开根

bzoj 1213 //1213: [HNOI2004]高精度开根

//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代码,与本人比较接近,进行对照研究,

相关文章:

  • 2021-10-21
  • 2022-01-02
  • 2022-12-23
  • 2021-06-13
  • 2021-08-12
  • 2022-01-30
  • 2021-12-17
猜你喜欢
  • 2021-07-05
  • 2022-12-23
  • 2021-08-14
  • 2021-07-09
  • 2021-06-07
  • 2021-06-27
  • 2022-12-23
相关资源
相似解决方案