sgu 111 分类: sgu 2015-02-09 14:35 123人阅读 评论(0) 收藏
sgu111
题意:大整数开方
解法:直接 二分+高精度(压位)
C语言手写高精度代码量还是比较大呀~
顺便发现了开方运算的一些神奇方法!
http://www.cnblogs.com/pkuoliver/archive/2010/10/06/1844725.html
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define size 4
#define Bit 10000
#define Half 5000
#define MAXN 300
struct number{int n[MAXN],l;}ans={0},mid={0},l={0},r={0},p={0};
char ch[MAXN*4]={'\0'};
inline struct number plus(struct number x)
{
int i;
x.n[1]++;
for(i=1;i<=x.l;i++)
{
if(x.n[i]>=Bit)
x.n[i]-=Bit,x.n[i+1]++;
else break;
}
if(x.n[x.l+1])x.l++;
return x;
}
inline int compare(struct number x,struct number y)
{
if(x.l > y.l)return 1;
else if(x.l < y.l)return -1;
else
{
int i;
for(i=x.l;i>=1;i--)
{
if(x.n[i] > y.n[i])return 1;
else if(x.n[i] < y.n[i])return -1;
else continue;
}
return 0;
}
}
int max(int a,int b){return (a>b)?a:b;}
inline struct number add(struct number x,struct number y)
{
int i,tl;
tl=max(x.l,y.l);
for(i=1;i<=tl;i++)
{
x.n[i]+=y.n[i];
if(x.n[i]>=Bit)
x.n[i]-=Bit,x.n[i+1]++;
}
if(x.n[tl+1])x.l=tl+1;
else x.l=tl;
return x;
}
inline struct number divi(struct number x)
{
int i;struct number ret={0};
for(i=x.l;i>=1;i--)
{
ret.n[i]+=x.n[i]>>1;
if(x.n[i]&1)
ret.n[i-1]+=Half;
}
ret.n[0]=0;
if(ret.n[x.l])ret.l=x.l;
else ret.l=x.l-1;
return ret;
}
inline struct number powi(struct number x)
{
struct number ret={0};
int i,j;
ret.l=x.l*2-1;
for(i=1;i<=x.l;i++)
for(j=1;j<=x.l;j++)
{
ret.n[i+j-1]+=x.n[i]*x.n[j];
ret.n[i+j]+=ret.n[i+j-1]/Bit;
ret.n[i+j-1]%=Bit;
}
for(i=1;i<=ret.l;i++)
{
ret.n[i+1]+=ret.n[i]/Bit;
ret.n[i]%=Bit;
}
while(ret.n[ret.l+1])
{
ret.l++;
ret.n[ret.l+1]+=ret.n[ret.l]/Bit;
ret.n[ret.l]%=Bit;
}
return ret;
}
inline void prt()
{
int i,t,tl;
printf("%d",ans.n[ans.l]);
for(i=ans.l-1;i>=1;i--)
{
t=ans.n[i],tl=0;
if(!t)tl=1;
else
while(t)
{
t/=10;tl++;
}
for(t=1;t<=size-tl;t++)printf("0");
printf("%d",ans.n[i]);
}
}
int main()
{
int i,j,k;
#ifndef ONLINE_JUDGE
freopen("sgu111.in","r",stdin);
freopen("sgu111.out","w",stdout);
#endif
scanf("%s",ch);
for(i=strlen(ch)-1,j=1;i>=0;i-=size,j++)
for(k=max(0,i-size+1);k<=i;k++)
{
p.n[j]*=10,p.n[j]+=ch[k]-'0';
}
p.l=j-1;
/*
while(l+1!=r)
{
mid=(l+r)>>1;
if(mid*mid>p)
{
r=mid;
}
else
{
l=mid;
}
}
ans=l;
*/
l.l=1;l.n[1]=1;
r.l=(p.l+1)/2+1;r.n[r.l]=1;
while(compare(plus(l),r))
{
mid=divi(add(l,r));
if(compare(powi(mid),p)>0)
r=mid;
else
l=mid;
}
ans=l;
prt();
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}
版权声明:本文为博主原创文章,未经博主允许不得转载。