您的位置:首页 > 编程语言 > C语言/C++

HDU 1063 Exponentiation

2013-07-11 21:03 706 查看
题目不难,一个高精度即可,但细节特别重要,特别是对于0的处理和小数点位置的确定特别重要,因此在高精度算完之后,需要【同时】确定小数点的正确位置和末尾0的处理,这道题的细节十分重要!!!我因此WA了3次。。

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 200
using namespace std;

typedef struct node{
char num[MAXN];
int len;
}bign;
int dot;

bign stringToBign(char *s)
{
int slen=strlen(s);
int p=-1,i=0;
bign g;
memset(g.num,0,sizeof(g.num));
while(1){
if(s[i]=='.') p=i;
else if(s[i]!='0') break;
i++;
}
int j=0;
for(;i<slen;i++){
if(s[i]=='.') p=i;
else g.num[j++]=s[i];
}
strrev(g.num);
for(i=0;i<j;i++){
g.num[i]-='0';
}
if(p==-1) dot=0;
else dot=slen-1-p;
g.len=j;
return g;
}
bign times(bign a,bign b)
{
bign s;
int t=0,i=0,j=0;
memset(s.num,0,sizeof(s.num));
while(i<a.len){
j=0;
while(j<b.len||t!=0){
t=a.num[i]*b.num[j]+s.num[i+j]+t;
s.num[j+i]=t%10;
t/=10;
j++;
}
i++;
}
s.len=j+i-1;
return s;
}
int main()
{
bign base,ans;
char s[10];
int n;
while(scanf("%s%d",s,&n)==2){
base=stringToBign(s);//字符串转换成bign,同时去除前导0和小数点,保留末尾的0,当成大整数直接高精
if(n==0) printf("1\n"); //特判0可以方便一点
else{
if(n==1) ans=base;
else{
ans=times(base,base);
for(int i=3;i<=n;i++) ans=times(ans,base);//高精度乘法
}
dot*=n;
int d=dot-ans.len;//判断小数点的位置
if(ans.len<1) printf("0\n");//答案0的处理
else{
int lo=0;
char op[MAXN+10]={0};
if(d>=0){确定小数点的位置
sprintf(op+(lo++),".");//纯小数
for(int i=0;i<d;i++) sprintf(op+(lo++),"0");
for(int i=ans.len-1;i>=0;i--) sprintf(op+(lo++),"%d",ans.num[i]);
}else{
d*=-1;
int j=ans.len;

//非纯小数
for(int i=0;i<d;i++){
sprintf(op+(lo++),"%d",ans.num[--j]);
}
sprintf(op+(lo++),".");
j--;
while(j>=0){
sprintf(op+(lo++),"%d",ans.num[j--]);
}
}

int i=strlen(op);
while(op[--i]=='0');//去除末尾0
if(op[i]=='.') i--;
op[i+1]=0;
printf("%s\n",op);

}
}

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息