PKU 1001 Solution using C++

#include <iostream>
#include <cmath>
using namespace std;

int grp[125]; /* 存放乘法之后的结果 */
int digi_a[5]; /* 把底数a的五位数字分开存放在一个数组中 */
int res[125]; /* 临时数组,用于乘法运算 */

void init() /* 初始化三个全局变量,每次进行计算之前都会初始化 */
    {
    int i;
    for (i=0;i<5;i++)
        digi_a[i]=0;
    for (i=0;i<125;i++)
        {
        grp[i]=0;
        res[i]=0;
        }
    }

int getinput(int *exp, int *digit) /* 格式输入 */
    {
    int i,j;
    int counter=0; /* 数出输入的数字是几位小数 */
    int dotted=0; /* 布尔量,标记输入的数字有没有小数点 比如000022 和 .02020 */
    char base[6]; /* 容纳输入的六位数字 */
    while (cin >> base[0]) /* 输入,包括检测是否输入结束 */
        {
        for (i=1;i<6;i++)
            cin >> base[i];
        cin >> *exp;
        for (i=0;i<=6;i++)
            {
            if (base[i]==’.’)
                {
                dotted=1;
                break;
                }
            }

        i=0,j=4;
        if (dotted)
            {
            while (i<6)
                {
                if (base[i]==’.’)
                    {
                    counter=5-i++;
                    continue;
                    }
                digi_a[j–]=base[i++]-48; /* 去掉小数点的五位数字传送给digi_a[5] */
                }
            *digit=counter;
            }
        else
            {
            while(i<5)
                digi_a[j–]=base[++i]-48;
            *digit=0;
            }
        return(0);
        }
    return(1); /* 输入结束 */
    }

void multiply() /* 乘法运算,原理是在小学里学的竖式乘法,本函数是竖式第一步:相乘 */
    {
    int i,j;
    for (j=0;j<125;j++)
        res[j]=0;
    for (i=0;i<5;i++)
        for (j=0;j<125;j++)
            res[i+j]+=grp[j]*digi_a[i];
    }

void sumup() /* 辅助乘法运算,让每个数位的数字小于一,也就是竖式乘法第二步:相加 */
    {
    int j;
    int right=0,left=0;
    for (j=0;j<124;j++)                    /* 124 : is the input smaller than 99999??? */
        {
        right=res[j]%10;
        left=(int)((res[j]-right)/10);
        res[j]%=10;
        res[j+1]+=left;
        }

    }

void findpow(int b) /* 调用乘法运算的循环结构,每次乘法都是把grp[125]和digi_a[5]相乘,其中grp[125]存放的是最新的运算结果;竖式乘法运用了线性思想 */
    {
    int j,k;
    if (b==0) /* 非零实数的零次方是一 */
        {
        grp[0]=1;
        return;
        }
    if (b==1) /* 一次方就不用计算了 */
        {
        for (j=0;j<5;j++)
            grp[j]=digi_a[j];
        }
    for (k=0;k<b-1;k++)
        {
        multiply();
        sumup();
        for (j=0;j<125;j++)
            grp[j]=res[j];
        }
    }

void formout(int digit) /* 格式输出,按照要求来吧 */
    {
    int j=124,k=0; /* j用来指向最左边的非零数字,k用来指向最右边的 */
    if (digit==0)
        {
        while (!grp[j])
            j–;
        while (j>=0)
            cout << grp[j–];
        return;
        }
    while (!grp[k] && k<digit)
        k++;
    while (!grp[j] && j>=digit)
        j–;
    if (j!=digit)
        while (j>=digit)
            cout << grp[j–];
    else
        cout << grp[j–];

    if (j!=k-1) cout << "."; /* grp[125]只是125位数字,在输出的时候通过文本输出打点 */
    while (j>=k)
        cout << grp[j–];
    cout << endl;
    }

int main()
    {
    int expn=0,digit=0;
    int IsEnd=0; /* 输入是否结束 */
    while (1) /* 输入结束靠break跳出 */
        {
        init();
        IsEnd=getinput(&expn,&digit);
        getchar();
        if (IsEnd) break;
        grp[0]=digi_a[0]+digi_a[1]*10+digi_a[2]*100+digi_a[3]*1000+digi_a[4]*10000; /* 初始化运算,把底数存放到grp[0]里面,不用担心没有分位,有进位函数 */
        if (!grp[0]) /* 零的幂是零 */
            {
            cout << "0" << endl;
            continue;
            }
        findpow(expn);
        formout(digit*expn);
        }
    return(0);
    }

 

 

哥干了三天,又翻工干了一天搞定了,看到网上贴这个题的人不多,就把自己这个0MS贴出来吧……

– END –

Advertisements
  1. 留下评论

Log in or fill out contact info to leave a reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: