748 - Exponentiation

一次AC。

先记下小数部分的长度,再做乘法,同时计算新的小数部分的长度

结果的几种特殊情况:

1.前导零 00000100000.0  红色的零就是前导零,可以直接在做预处理和乘法的时候搞掉。

   这里需要注意 00000.87468  这种开头全是0的情况,需要变成 .87468

    以及 0.00001   这种前导零延伸到小数部分的情况  

 

2.无用的后导零  如:0.00100000000 红色的零就是无用的后导零 

  这里需要注意  10000000 和10000.0100  这种有的后道零是有用的的情况

  还好题目说 r<0,否则还要考虑 0.0这种情况

由于写的时候思路有点乱,所以代码也很……  

如果有什么疑问或者我有什么错误,敬请回复。

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=20000;
struct bign  //LRJ白书的模版
{
  int len,s[maxn];
  bign()
  {
      memset(s,0,maxn);len=1;
  }
  bign operator = (const char* num)
  {
      len=strlen(num);
      for(int i=0;i<len;i++) s[i]=num[len-i-1]-'0';
      return *this;
  }
  bign operator = (const int num)
  {
      char a[maxn];
      sprintf(a,"%d",num);
      *this=a;
      return *this;
  }  
  bign clear()
  {
      int flag=1;
      for(int i=len;i>=0;i--)
        if(s[i]!=0)
          {
            flag=0;
            len=i+1;break;
          }
      if(flag) len=1;
      return *this;
  }
  bign operator * (const bign b)
  {
      bign c;
      c.len=b.len+len+1;
      for(int i=0;i<b.len;i++)
        for(int j=0;j<len;j++)
          {
            c.s[j+i]+=s[j]*b.s[i];
            if(c.s[i+j]>=10)
            {
                c.s[i+j+1]+=c.s[i+j]/10;
                c.s[i+j]=c.s[i+j]%10;
            }
          }
      if(c.s[c.len]==0) c.len--;
      c.clear();
      return c;
  }
  string str() const
  {
      string res="";
      for(int i=0;i<len;i++) res=(char)(s[i]+'0')+res;
      if(res=="") res="0";
      return res;
  }
};
int main()
{
  char r1[1000];
  int n;
  while(cin>>r1>>n)
  {
      
    int tmp_num,num;
    bign r,tmp;
      int i,j;
      
    //读入+预处理 
      for(i=0,j=0;j<5;)
      {
        if(r1[i]=='.') 
        {
          tmp_num=5-i;
          i++;
        }
        r1[j++]=r1[i++];
      }
      r1[5]=0;//记得结尾标志
      r=r1;r.clear();
    tmp=r1;tmp.clear();
    //printf("debug: tmp_num=%d\n",tmp_num);
    
    //计算去掉小数点后的整数的结果 
    num=tmp_num;
      for(i=1;i<n;i++) 
    {
      r=r*tmp;//注意每次应该乘上tmp(读入的乘数),而不是r(算了一半的结果)
      num=num+tmp_num;//同上,千万别写num=num+num; 
    }
    //printf("debug: r.len-1=%d\n",r.len-1);
    //printf("debug: num=%d\n",num);
    
    //输出 
    if(r.len-1<num) cout<<".";//如果整数部分全是零 
    i=1;
    while(r.len-1<num-i)//如果小数部分还有零 
      cout<<"0";i++;
    int kill=r.len;
    for(i=0;i<r.len;i++)//找出最后一个非无用后导零的数的位置 
      if(r.s[i]!=0) 
      {
          kill=i;
          break;
      }
    if(kill>num-1) kill=num-1;//整数部分的后导零是有用的。不能删。 
    for(i=r.len-1;i>=0;i--)
    {
      cout<<r.s[i];
      if( i==num )cout<<'.'; 
      if( i==kill) break;//最后一个有用的数已经输出,后面的全是后导零了。 
    }
    cout<<endl;
    //cout<<r.str()<<endl;
  }
  return 0;
}

 

我在写这篇随笔的时候我的chrome崩溃了三次我会瞎说?!!!

posted @ 2012-12-31 13:13  Wxy191  阅读(180)  评论(0编辑  收藏  举报