poj1001解题报告

     这一道题在poj上的AC ratio很低,客观上是因为这道题的细节较多,特别是在输出格式上的细节。在discuss中,我看到有一些人贴出代码,这个做法我不赞同,不管怎么 样,如果只是不加深入研究的复制粘贴AC,那也没有任何意义。给出一些测试数据帮助思考,我还是比较赞同的。

     算法是一个半数学半工程的学科,所以它首先是严谨的,另外它又有别于数学更加贴近实际的问题。算法解决问题,不单纯依赖数学,生活实际中的问题有一些更注重策略和解决方案,而非数学。

     希望以上的代码和叙述能给后来者一些有用的提示,切忌直接拷贝代码哦,如果能帮到你,我会很惊喜。

#include <cstdio>

#include <vector>

#include <cstring>

using namespace std;



struct BigNumber

{

    BigNumber()

    {

        body.clear();

        dot = 0;

    }

    vector<int> body;

    int dot;

};



void display(BigNumber b)

{

    int len = b.body.size();

    //去掉大整数的前导零

    int rid = len -1;

    while(b.body[rid] == 0)

    {

        rid--;

    }

    len = rid + 1;

    int dot = b.dot;



    if(dot == 0)//如果没有小数部分,则直接输出

    {

        int i;

        for(i=len-1;i>=0;i--)

            printf("%d", b.body[i]);

        printf("\n");

    }

    else

    {

        if(dot <= len)

        {

            //get rid of trailing zeros

            int i = 0;

            while(b.body[i] == 0 && i<= dot-1)

            {

                i++;

            }

            int j;

            for(j=len-1;j>=i;j--)

            {

                if(j+1 == dot)

                    printf(".");

                printf("%d", b.body[j]);

            }

            printf("\n");

        }

        else

        {

            int i=0;

            while(b.body[i] == 0 && i <= dot-1)

            {

                i++;

            }



            int delta = dot - len;

            printf(".");

            while(delta>0)

            {

                printf("0");

                delta--;

            }

            int j;

            for(j=len-1;j>=i;j--)

                printf("%d", b.body[j]);

            printf("\n");

        }

    }

}



//大数乘法需要保证无前导零

BigNumber multi(BigNumber sa, BigNumber sb)

{

    int lena = sa.body.size();

    int lenb = sb.body.size();



    BigNumber ret;

    int i, j;

    for(i=0;i<lena;++i)

    {

        for(j=0;j<lenb;++j)

        {

            int item = sa.body[i] * sb.body[j];

            // put item into ret's (i+j)th space

            while(i+j>=ret.body.size())

            {

                ret.body.push_back(0);

            }

            //for ret, here char is used as int,这里使用char来存每一位,不知道会不会溢出?

            ret.body[i+j] += item;

        }

    }



    ret.dot = sa.dot + sb.dot;

    //do shifting on ret

    int k;

    for(k=0;k<ret.body.size();++k)

    {

        if(ret.body[k]>=10)

        {

            if(k+1==ret.body.size())

                ret.body.push_back(0);

            ret.body[k+1] += ret.body[k] / 10;

            ret.body[k] = ret.body[k] % 10;

        }

    }



    return ret;

}



BigNumber solve(BigNumber s, int n)

{

    if(n == 1)

        return s;

    if(n%2 == 0)

    {

        BigNumber b = solve(s, n/2);

        return multi(b, b);

    }

    else

    {

        BigNumber c = solve(s, (n-1)/2);

        BigNumber d = multi(c, c);

        return multi(d, s);

    }

}
char s[10]; int n; int main() { while(scanf("%s%d", s, &n) == 2) { struct BigNumber ini; int len = strlen(s); int i; for(i=len-1;i>=0;i--) { if(s[i] == '.')// here, i == len -1 is impossible ini.dot = len-1 - i; else ini.body.push_back(s[i]-'0'); } BigNumber res = solve(ini, n); display(res); } return 0; }

你可能感兴趣的:(poj)