Vijos 1010 清帝之惑之乾隆

背景

乾隆,雍正的第四子,在位60年,退位后又当了三年太上皇,终年89岁。
乾隆即位之初,实行宽猛互济的政策,务实足国,重视农桑,停止捐纳,平定叛乱等一系列活动中,充分体现了他的文治武功,乾隆帝向慕风雅,精于骑射,笔墨留于大江南北,并是一个有名的文物收藏家。清宫书画大多是他收藏的,他在位期间编纂的《四库全书》共收书3503种,79337卷,36304册,其卷数是《永乐大典》的三倍,成为我国古代思想文化遗产的总汇。
乾隆好游江南,喜欢江南的山水,喜欢江南的人文,喜欢江南的才气,同时他也喜欢江南的汉族美女。

描述

话说乾隆带着他的宰相刘罗锅和你出巡江南,被杭州城府邀请去听戏,至于什么戏,那就不知了。乾隆很高兴,撒酒与君臣共享。三更欲回住处,可是乾隆这人挺怪,他首先要到西湖边散散步,而且命令不准有人跟着他。
小醉,步于西湖岸,停于断桥前,突闻琴声悠悠,歌儿婉婉。这乐曲不哀伤不愁怅,少了一分怨女的羁绊,多了一分少女的期盼。乾隆走上前去,视其背影,为一女子手抚古琴,悠悠而唱。可是这么晚了,小女怎么还不回家呢,莫非是她起早床?乾隆走上前去,小声问道:“伊为何未宿?”,小女沉默片刻,转身而来。顿时,顿时,顿时!!!!!乾隆惊呆了!!!!哇!!!!噻!!!!!!这人,这伊!!!!原来!!!!!!!不是一个美女(狂汗ing)。小女并未回答她的话,只是与乾隆侃了侃诗。乾隆兴哉,问其曰:“不知偶能助伊否?”,小女曰:“偶无所以助,且有一事相求,愿君能解之。”
乾隆一看,立刻晕到在地,片刻而起,曰:“明日必解之”,且去。
回到家中,乾隆夜召你“入寝”,曰:“如此姑娘,如此情调,如此罗曼蒂克,竟然丢一个如此煞风景之问”,一边发气,一边把这个问题交给你。你一看,顿然发现,原来是用蝌蚪文写的:
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 <= 9999.9) and n is an integer such that 0 < n <= 250.
此时的你,已经是皇帝身边的小太监,自然有必要为皇上解决此题。

格式

输入格式

The input will consist of a set (less than 11) 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 to 10.

输出格式

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.

样例1

样例输入1

95.123 2
0.4321 5
5.1234 7
6.7592 3
98.999 5
1.0100 10

样例输出1

9048.385129
.01506334182914325601
92663.3181348508776705891407804544
308.806114738688
9509420210.697891990494999
1.10462212541120451001

题解

这道题目可以理解为求一个实数R的n次方,其中0.0 < R <= 9999.9,0 < n <= 250,所以可以发现使用浮点数是不能非常精确地保存精度要求这么高的结果的。于是决定使用字符串模拟操作。
再来分析小数点。因为实数的话进行大数乘法比较麻烦,所以我们可以使用一个变量p来保存小数点后数字的个数,从而将小数的乘法化为整数的乘法。
例如:
计算1.12的3次方,我们可以计算一下结果有6位小数(2*3),所以我们可以先计算112的三次方,然后将结果的后六位置为小数。计算得到112的3次方等于1404928,将后6位设为小数则位1.404928。
当然我们需要考虑一下整数部分最前面的0和小数部分最后面的0是不需要输出的。
除此之外,因为R最多是6位,所以不算小数点的话最多有5或6位(有可能六位里面都没有小数点),所以是可以用整数来表示的。所以我们的大数乘法可以用字符串乘以int的简化方法进行。
在我的程序中:

  • 字符串s用于存放计算结果;
  • init()函数用于将字符串代表的值初始化为1;
  • multi(int a)函数用于将字符串代表的数乘以一个成型变量a,并将结果保存在字符串s中;
  • output()函数用于输出最终的结果。
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 11000;
char s[maxn], t[10];
int a, p, n;
void init()
{
    memset(s, 0, sizeof(s));
    s[0] = 1;
}
void multi(int a)
{
    int c = 0;
    for (int i = 0; i < maxn; i ++)
    {
        c += s[i] * a;
        s[i] = c % 10;
        c /= 10;
    }
}
void output(int p)
{
    int i, j;
    for (i = maxn-1; i >= p && s[i] == 0; i --);
    for (j = 0; j < p && s[j] == 0; j ++);
    for (; i >= p; i --)
        printf("%d", s[i]);
    if (p > j)
        putchar('.');
    for (; i >= j; i --)
        printf("%d", s[i]);
    putchar('
');
}
int main()
{
    while (~scanf("%s%d", t, &n))
    {
        int len = strlen(t);
        p = 0;
        a = 0;
        for (int i = 0; i < len; i ++)
        {
            if (t[i] == '.')
            {
                p = (len - 1 - i) * n;
            }
            else
            {
                a = a * 10 + (t[i] - '0');
            }
        }
        init();
        for (int i = 0; i < n; i ++)
        {
            multi(a);
        }
        output(p);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xianyue/p/6963245.html