zoukankan      html  css  js  c++  java
  • 【原】 POJ 1001 Exponentiation 大整数乘法 解题报告

    http://poj.org/problem?id=1001

     
    方法:
    大整数乘法
    这题没什么好说的,直接用字符串模拟整个过程

    Description

    Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.
    This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

    Input

    The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

    Output

    The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

    Sample Input

    95.123 12

    0.4321 20

    5.1234 15

    6.7592 9

    98.999 10

    1.0100 12

    Sample Output

    548815620517731830194541.899025343415715973535967221869852721

    .00000005148554641076956121994511276767154838481760200726351203835429763013462401

    43992025569.928573701266488041146654993318703707511666295476720493953024

    29448126.764121021618164430206909037173276672

    90429072743629540498.107596019456651774561044010001

    1.126825030131969720661201

     
       1: #include <iostream>
       2: #include <string>
       3:  
       4: using namespace std ;
       5:  
       6: //大浮点数相乘,此时系统提供的精度远远不能达到要求
       7:  
       8: string multiply_bignum(const string& lhs,const string& rhs)
       9: {
      10:     //if( lhs=="0" || rhs=="0" )
      11:     //    return "0" ;
      12:  
      13:     //lengths of the two operators , including dot
      14:     size_t len1 = lhs.size() ;
      15:     size_t len2 = rhs.size() ;
      16:     int index=0 ;
      17:  
      18:     //carefully judge whether exist 0
      19:     //.000 or 0.000 or 000.
      20:     for( index=0 ; index<len1 ; ++index)
      21:     {
      22:         if( lhs[index]!='0' && lhs[index]!='.' )
      23:             break;
      24:     }
      25:     if( index==len1 )
      26:         return "0" ;
      27:  
      28:     for( index=0 ; index<len2 ; ++index)
      29:     {
      30:         if( rhs[index]!='0' && rhs[index]!='.' )
      31:             break;
      32:     }
      33:     if( index==len2 )
      34:         return "0" ;
      35:  
      36:     //copy the two operators , because later may delete their dots
      37:     string s1(lhs);
      38:     string s2(rhs);    
      39:     //max length of the result
      40:     size_t lenResult = len1+len2 ;
      41:  
      42:     int val1,val2,tmpval,mul_carry,sum_carry ;
      43:     int i,j,k,t,m ;
      44:  
      45:     //initialize the result to 0
      46:     string result(lenResult,'0') ;    
      47:  
      48:     size_t dotnum1,dotnum2,dotnumResult;
      49:     //find the positions of the dots in the two operators
      50:     string::size_type pos1 = s1.find(".") ;
      51:     string::size_type pos2 = s2.find(".") ;
      52:     string::size_type dotpos ;
      53:  
      54:     if( pos1 == string::npos )   //there is no dot
      55:         dotnum1 = 0 ;
      56:     else                         //the operator is float
      57:     {
      58:         s1.erase( pos1 , 1 ) ;   //delete the dot , 12.34-->1234
      59:         dotnum1 = len1-pos1-1 ;  //number of the digit behind the dot
      60:         --len1 ;                 //now the length decrease 1
      61:     }
      62:  
      63:     if( pos2 == string::npos )
      64:         dotnum2 = 0 ;
      65:     else
      66:     {
      67:         s2.erase( pos2 , 1 ) ;
      68:         dotnum2 = len2-pos2-1 ;
      69:         --len2 ;
      70:     }
      71:  
      72:     dotnumResult = dotnum1+dotnum2 ;    //number of digit behind the dot in the result
      73:     dotpos = lenResult-dotnumResult-1 ; //the position of the dot in the result
      74:  
      75:     for( i=len2-1 , k=lenResult-1 ; i>=0 ; --i ,--k )  //s1*s2
      76:     {
      77:         string tmpresult(lenResult,'0') ;
      78:         mul_carry = 0 ;    //carry of multiply in calculating the tmpresult
      79:         sum_carry = 0 ;    //carry of sum in calculating the final result
      80:         val2 = s2[i]-'0';  //get the digit of s2 in reverse order to simulate the process of multiply
      81:  
      82:         for( j=len1-1 , t=k ; j>=0 ; --j , --t )
      83:         {
      84:             val1 = s1[j]-'0' ;
      85:             tmpval = val1*val2 + mul_carry ;
      86:             mul_carry = tmpval/10 ;
      87:             tmpresult[t] = tmpval - 10*mul_carry + '0' ;
      88:         }
      89:         tmpresult[t] = mul_carry + '0' ;  //put the final carry to the tmpresult
      90:  
      91:         for( m=lenResult-1 ; m>=0 ; --m ) //update the result
      92:         {
      93:             tmpval = (result[m]-'0') + (tmpresult[m]-'0') + sum_carry ;
      94:             sum_carry = tmpval/10 ;
      95:             result[m] = tmpval - 10*sum_carry + '0' ;
      96:         }
      97:     }
      98:     string::size_type resultBeginPos ;
      99:     string::size_type resultEndPos ;
     100:     if( dotnumResult == 0 )  //there is no dot
     101:     {
     102:         resultBeginPos = result.find_first_not_of('0') ;
     103:         return result.substr(resultBeginPos); ;
     104:     }
     105:     else
     106:     {
     107:         result.insert( ++dotpos , 1 , '.' );  //insert the dot into result
     108:  
     109:         resultBeginPos = result.find_first_not_of('0') ;
     110:         resultEndPos = result.find_last_not_of('0') ;
     111:         if( resultBeginPos == dotpos )  //0.123000
     112:             return result.substr( resultBeginPos , resultEndPos-resultBeginPos+1 ) ;
     113:         else if( resultBeginPos < dotpos ) //12.3400 or 12340.0000
     114:         {
     115:             if( resultEndPos > dotpos )  //12.3400
     116:                 return result.substr( resultBeginPos , resultEndPos-resultBeginPos+1 ) ;
     117:             if( resultEndPos == dotpos )  //12340.0000
     118:                 return result.substr( resultBeginPos , resultEndPos-resultBeginPos );
     119:         }    
     120:     }
     121: }
     122:  
     123: //divide and conquer
     124: string power_bignum(const string& R,int n)
     125: {
     126:     if(n==0)
     127:         return "1" ;
     128:     if(R=="0")
     129:         return "0" ;
     130:  
     131:     if(n==1)
     132:         return multiply_bignum( R , "1" ) ;
     133:     string tmpresult = power_bignum(R,n/2);
     134:     if( n%2 != 0 )
     135:         return multiply_bignum( R , multiply_bignum(tmpresult,tmpresult) );
     136:     else
     137:         return multiply_bignum(tmpresult,tmpresult) ;
     138: }
     139:  
     140: void run1001()
     141: {
     142:     string r;
     143:     int n;
     144:     while(cin>>r>>n)
     145:         cout<<power_bignum(r,n)<<endl;
     146: }
  • 相关阅读:
    C# 在代码中创建 DataTable 和从数据库取出的数据 DataTable
    C#编程数据库操作之DataTable
    测试代码的运行时间(C#)
    时间天数 的使用
    遍历panel 上的控件,然后操作
    break 和 continue区别
    DataTable排序的一般方法
    MG758 GIS数据采集终端
    C#中DataTable
    android InputStream相关类
  • 原文地址:https://www.cnblogs.com/allensun/p/1869330.html
Copyright © 2011-2022 走看看