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; }

posted on 2012-04-24 19:00  涅槃火凤  阅读(476)  评论(0编辑  收藏  举报

导航