整个题库的第二题,原本都没有屑于去做,突发奇想抱着秒杀的心态去写了代码,却硬生生地吃了4个WA..
【思路】先去除掉小数点,进行最基本的高精度乘法运算,再在运算得到的结果中添加小数点输出。
【前铺】让我们先来看一看数组究竟需要设多大?数据范围是最大为99.999,则近似为100.000,当n=25时,至多有125个零,即最多占用125位。
【易错点】*数据1:10.000 01,如果直接从后往前去零的话,数据输出会变成1。所以删除末位多余零的范围是末位起,截止至小数点后。
*数据2:000010 01,这个数据中根本不存在小数点!一开始我误以为6位中必然存在一位为小数点,所以将num的数组下标开为0..5,但这种情况下占用空间为0..6。我的解决方法是若当前数字存在小数点,则将其最后一位,即倒序摆放后的Num[0]设为0,整数和小数就可以统一处理了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 const int MAXN=125+5; 7 char s[MAXN]; 8 int num[MAXN]; 9 int ans[MAXN]; 10 int n,ed,pos=0; 11 12 void switchnum()//将字符串转换为数字,并记录下小数点位置 13 { 14 bool have=false; 15 for (int i=0;i<7;i++) 16 { 17 if (s[i]=='.') 18 { 19 pos=(6-i)*n;have=true; 20 } 21 else 22 { 23 if (have) num[5-(i-1)]=s[i]-'0'; 24 else num[5-i]=s[i]-'0'; 25 } 26 } 27 if (have) num[0]=0; 28 for (int i=0;i<6;i++) 29 ans[i]=num[i]; 30 } 31 32 void mul() 33 { 34 int temp[MAXN]; 35 memset(temp,0,sizeof(temp)); 36 for (int i=0;i<=ed;i++) 37 for (int j=0;j<=5;j++) 38 { 39 temp[i+j]+=ans[i]*num[j]; 40 if (i+j>0 && temp[i+j-1]>9) 41 { 42 temp[i+j]+=temp[i+j-1]/10; 43 temp[i+j-1]%=10; 44 } 45 } 46 ed=ed+5; 47 if (temp[ed]>9) //不要写成>10 48 { 49 ed++; 50 temp[ed]=temp[ed-1]/10; 51 temp[ed-1]%=10; 52 } 53 for (int i=0;i<=ed;i++) ans[i]=temp[i]; 54 } 55 56 void output() 57 { 58 bool f=false; 59 int op=0; 60 for (int i=0;i<pos;i++) //整数部分末位的零不能删去 61 { 62 if (ans[i]>0) break; 63 op++; 64 } 65 for (int i=ed;i>=op;i--) 66 { 67 if (i==pos-1) //这里不能写成(i=pos-1)否则赋值,不要写成(i==pos+1) 68 { 69 cout<<'.'; 70 f=true; 71 } 72 if (ans[i]>0) f=true; 73 if (f) cout<<ans[i]; 74 } 75 cout<<endl; 76 } 77 78 int main() 79 { 80 while (scanf("%s%d",s,&n)!=EOF) 81 { 82 ed=5; //除去小数点外的初始末位为5 83 switchnum(); 84 for (int i=1;i<n;i++) mul(); 85 output(); 86 } 87 }