POJ-北大acm 1001 exponentiation 解題報告與bug

     嚴格來講本解法不能算大數相乘的通用算法, 而只是針對題目中(0.0 < R < 99.999)的trick. 因R位數很小, 因此本算法思路是把R擴大倍數而轉成整數(99.999 -> 99999), 而後把每次乘積累加到結果數組中, 算法比較簡單. 算法

     同時, 發現POJ本題的審覈程序有bug. 題目要求對尾部(trailing)無效的0不能打印出來, 但實際審覈時沒有這麼嚴謹, 多是測試數據沒有涵蓋全部邊界或者其它緣由. 具體狀況是: 對小於0的結果打印時不去掉尾部的0, 審覈程序依然accepted. 舉個例子, 對於小於1的R(如0.10000), 不論n取多少(如取3), 其乘方的結果是小於0的小數`.001000000000000`, 若是算法直接打印`.001000000000000`依然accepted, 但依題目的要求真正結果應是`.001`. 即把後文算法中以下注釋掉的4行代碼打開纔是嚴格的, 但POJ的bug致使註釋了也能accepted. 數組

//while (product[j] == 0) // trim trailing zeros
//{
//	j++;
//}

如下是題目與解法(C語言), 文末貼了參考來源 less

                                          Exponentiation 測試

Time Limit: 500MS Memory Limit: 10000K
Total Submissions: 116340 Accepted: 28271

Description ui

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 R n  where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

Input spa

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 .net

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 code

95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12

Sample Output orm

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
#include <stdio.h>
#include <string.h>

int len; // total length of exponentiation result
int product[126] = {0}; // storing result, at most length 5*25 + 1 = 126

void multiply(int a[], int n)
{
    int i;
    int carry = 0; // a carry number in multiplying
    for (i = 0; i < len; i++)
    {
        int temp = a[i]*n + carry;
        a[i] = temp % 10;
        carry = temp / 10;      
    }
    while (carry)
    {
        a[i++] = carry % 10;
        carry /= 10;
    }
    len = i;
}

int main(int argc, char* argv[])
{
    int n;  // power n
    char s[6]; // real number R, at most the length is 6
    while (scanf("%s %d", s, &n) != EOF)
    {
        int position=0, i=0, num=0, j=0;
        for (i=0; i<strlen(s); i++) 
        {
            if (s[i] == '.')
            {
                position = (strlen(s) - 1 - i) * n; // calculate decimal point position after R^n
            }
            else
            {
                num = num*10 + s[i] - 48; // transfer float to integer
            }       
        }
        
        // product calculation 
        product[0]=1;
        len = 1;
        for (i = 0; i < n; i++)
        {
            multiply(product, num);
        }

        // format output
        if (len <= position) // product is less than 1
        {
            printf("."); // print decimal point
            for (i=0; i<position-len; i++)
            {
                printf("0"); // print zero between decimal point and decimal
            }

            j = 0;
            //while (product[j] == 0) // trim trailing zeros
            //{
            //    j++;
            //}
            for (i=len-1; i>=j; i--)
            {
                printf("%d", product[i]);
            }
        }   
        else
        {
            j=0;
            while (product[j]==0 && j<position) // trim trailing zeros
            {
                j++;
            }
            for (i=len-1; i>=j; i--)
            {
                if (i+1 == position) // cause index in C language starts from 0
                {
                    printf(".");
                }
                printf("%d", product[i]);
            }
        }
        printf("\n");
    }
}
參考: http://blog.csdn.net/xiongheqiang/article/details/7471661
相關文章
相關標籤/搜索