ACM1001

希望自己能坚持下去做OJ吧。
BTW AC的感觉太爽了。
全题: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.

出现过的问题:多次循环时需要用getchar()
清理一下上一次的缓存的回车,否则会产生奇奇怪怪的结果。
然后是审题,这次在题里明确写出了怎么结束……然后自己折腾了半天各种换东西……

基本是一个构建了150位精度的一个计算模式,里面包含了多位乘一位的函数,多位乘多位的函数,多位加多位的函数。都是在本题的基础上建立的(150位),然后两三个辅助函数减轻工作量。
如果有需要欢迎联系我,这里不再多注解。

#include <iostream>
#include <math.h>
#include <string>
using namespace std;
int* add(int* a, int* b); 
int* bymmul(int* a, int* b);
int* byonemul(int* a, int b);
int pdflx(int* a);
int pdintx(int* a);
bool text(int k);

int* bymmul(int* a, int* b, bool yu);

int main()

{
    string a; int n;
    while (cin >> a >> n)
    {
        string s;
        s = "";
        char R[6];
        int mark = -1;
        int N;
        int cla[5];

        int k = 4;
        for (int i = 0; i < 6; i++)
        {
            R[i] = a[i];
            if (R[i] == '.')mark = i;
        }
        N=n;
        int *res = new int[150];
        for (int i = 0; i < 150; i++)
        {
            res[i] = 0;

        }

        bool marks = 1;
        if (mark == -1)
        {
            int claa[6];

            k = 5;
            for (int i = 0; i < 6; i++)
            {

                res[k] = R[i] - 48;
                claa[k] = res[k];
                k--;
            }

            for (int i = 0; i < 6; i++)
            {
                if (claa[i] != 0)
                    marks = false;
            }
            if (marks)
            {
                s = "0";
                cout << s<<endl;
                continue;
            }
            for (int i = 0; i < N - 1; i++)
            {
                res = bymmul(res, claa, true);
            }
            for (int i = pdintx(res); i >= 0; i--)
            {
                s += (char)(res[i] + 48);
            }

            cout << s;
        }

        //六位中小数的位数
        int point_n;
        point_n = 5 - mark;
        //计算

        //初始数据进入res

        for (int i = 0; i < 6; i++)
        {
            if (i == 5 - point_n) { continue; }
            res[k] = R[i] - 48;
            cla[k] = res[k];
            k--;
        }

        for (int i = 0; i < 5; i++)
        {
            if (cla[i] != 0)
                marks = false;
        }
        if (marks)
        {
            s = "0";
            cout << s<<endl;
            continue;
        }
        for (int i = 0; i < N - 1; i++)
        {
            res = bymmul(res, cla);
        }
        //输出整数
        int POINT_N = point_n*N;//最后一位整数的下标;
        bool e_int = pdintx(res) >= POINT_N;
        bool e_flo = pdflx(res) < POINT_N;

        if (e_int&&e_flo)
        {
            for (int i = pdintx(res); i >= POINT_N; i--)
            {
                s += (char)(res[i] + 48);
            }
            s += '.';
            for (int i = POINT_N - 1; i >= pdflx(res); i--)
            {
                s += (char)(res[i] + 48);
            }
        }
        else if (e_int && !e_flo)//有整数没小数
        {
            for (int i = pdintx(res); i >= POINT_N; i--)
            {
                s += (char)(res[i] + 48);
            }
        }
        else if ((!e_int) && e_flo)//有小数没整数
        {
            s += '.';
            for (int i = POINT_N - 1; i >= pdflx(res); i--)
            {
                s += (char)(res[i] + 48);
            }
        }
        cout << s<<endl;


    }
}
bool text(int k)
{
    int b = k / 10;
    if (b == 0)return true;
    else return false;
}

//从后往前寻找第一个非零
int pdintx(int* a)
{
    for (int i = 149; i >= 0; i--)
    {
        if (a[i] != 0)
            return i;
    }
    return -1;
}
//从前往后寻找第一个非零
int pdflx(int* a)
{
    for (int i = 0; i < 150; i++)
    {
        if (a[i] != 0)
            return i;
    }
    return -1;
}

int* byonemul(int* a, int b)
{
    int * x = new int[150];
    for (int i = 0; i < 150; i++)
    {
        x[i] = 0;

    }
    int p = pdintx(a);
    int ex = 0;
    for (int i = 0; i <= p; i++)
    {
        x[i]=a[i] * b % 10 + ex;
        ex = (int)(a[i] * b / 10);
        if ((int)(x[i] / 10) == 1)
        {
            x[i] -= 10;
            ex++;
        }
    }
    x[p + 1] = ex;
    return x;

}

int* bymmul(int* a, int* b)//a150位,b5位
{
    int* x; int* y;

        x = byonemul(a, b[0]);
        for (int n = 1; n < 5; n++)
        {
            y = byonemul(a, b[n]);
            for (int k = 0; k < n; k++) {
                for (int i = 149; i > 0; i--)
                {
                    y[i] = y[i - 1];
                }
                y[0] = 0;
            }
            x = add(x, y);
        }
        delete[] y;
        return x;
}

int* bymmul(int* a, int* b,bool yu)//a150位,b6位
{
    int* x; int* y;

    x = byonemul(a, b[0]);
    for (int n = 1; n < 6; n++)
    {
        y = byonemul(a, b[n]);
        for (int k = 0; k < n; k++) {
            for (int i = 149; i > 0; i--)
            {
                y[i] = y[i - 1];
            }
            y[0] = 0;
        }
        x = add(x, y);
    }
    delete[] y;
    return x;
}
int* add(int* a, int* b)
{
    int* x = new int[150];
    int ex = 0;
    for (int i = 0; i < 150; i++)
    {
        x[i] = ex + a[i] + b[i];
        if (x[i]>=10) 
        { 
            ex=1;
            x[i] -= 10;
        }
        else
            ex = 0;
    }
    return x;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值