学习下ACM的题目

//参考:https://my.oschina.net/leopardsaga/blog/123495?fromerr=atjgdwtv

//小数点的位置,小数点后面m和n位的数相乘,最后小数点后有m+n位 
//最后有多少位,m位乘以n位最后的结果有m+n或者m+n-1位 
//将小数看成是整数处理,处理完成后再加上小数点
//大数相乘注意点:进位,位数(因为位数不定,所以计算结束后要处理一下),计算时是从个位开始的,而书写的时候从高位开始的,要反转 
//两种思路:1.乘数和被乘数都逐位相乘;2.乘数按逐位,被乘数作为一个整体(适合被乘数比较小,基本数据类型可以表示) 
//题目要求0.0<r<99.999    0<n<=25 
#include<stdio.h>
#include<string.h>


void multiply(int result[],int value, int& len, int n){
int carry=0;//进位 
for(int i=0; i<n; i++){//幂指数
 int j;
 for(j=0; j<len; j++){//将结果数组中的每一位和根相乘 
  int temp=result[j]*value+carry;
  carry=temp/10;
  result[j]=temp%10;//存储的时候是反转的 
 } 
 while(carry){
  result[j++]=carry%10;//结果数组由于进位,最后结果的位数开始增加
carry/=10; 
 }
 len=j;
}
}
int main() {
char bott[6];//根 
int n=0;//次幂 
while(scanf("%s %d",bott,&n)!=EOF){ 
int result[126]={0};//最大size=5+5+...+5+1=5*25+1=126;  
int num=0;
int afterdot=0;
 for(int i=0; i<strlen(bott); i++) {
  if(bott[i]=='.')//后面用else表示对于bott[i]=='0'时候,不执行else中的语句 
   afterdot=(strlen(bott)-1-i)*n; //是结果数组的下标 ,按前向遍历结果数组 
  else
   num=num*10+bott[i]-'0';
 }
result[0]=1;
int len=1;//表示结果数组中目前一共有几位数:如23,则len=2 
multiply(result,num,len,n);

//输出 
//因为之前没有考虑小数点,所以输出的时候要往结果数组中填0
//如0.01*0.01=0.0001-结果数组中只有一个|1| | |.|    这种的话就要补0,补几个0? len和afterdot的差值 
//另一种1.2*1.2=1.44- 结果数组中为|4|4|1|,小数点应该在|4|4|.|1|      这种不需要补0 
if(len<afterdot){ //也就是说value是小于0的实数
 printf(".");//纠正:printf('.');是错误的,应该是printf("%c",'.') 
 for(int i=0; i<afterdot-len; i++)
   printf("0");
   //少考虑种情况
//0.100*0.100=0.01在结果数组中为|0|0|0|0|1|,小数点加在|0|0|0|0|1| |.|,输出.01而不是.010000 
//因为把小数当成是整数考虑了,所以0.100后面的0必须要考虑,因此下面的程序要修改
//fix_start 
   int j=0;
   while(result[j]==0)
   j++;
   //fix_end
 for(int i=len-1; i>=j; i--)
   printf("%d",result[i]);
 /*
 bool flag=false;//碰到第一个非0的时候就置为true 
 for(int i=len-1; i>=0; i--){
   if(result[i]!=0)
     flag=true;
   if(flag)
     printf("%d",result[i]);
      }
 */
}
else{ //value是大于0的实数 
 //同样没有考虑上面那种情况
 //2.100*2.100=4.41在结果数组中为|0|0|0|0|1|4|4|,小数点加在|0|0|0|0|1|4|.|4|,输出的是4.41而不是4.410000
 int j=0;
 while(result[j]==0)
 j++;
 for(int i=len-1; i>=j; i--){
   if(i+1==afterdot)
     printf(".");
   printf("%d",result[i]);
 }
 //abondan
 /*
 bool flag=false;
 for(int i=len-1; i>=0; i--){
  if(result[i]!=0)
   flag=true;
  if(flag){
   //if(i=len-afterdot)
   if(i+1==afterdot) 
     printf(".");
   printf("%d",result[i]);
}
 }
 */
 //abandon
 /*
 for(int i=len-1; i>=0; i--){
  if(i=len-afterdot){
   printf('.');
   printf("%d",result[i]);
}
  else
   printf("%d",result[i]);
 }
 */
}
printf("\n");
  }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值