/*
对于一个实数R(0<R<99.999),要求写程序精确计算R的n次方,其中n是整数。并且0<n<=25
输入:输入包括多组R和n,R的值占第1列到第六列,n的值占第8和第9列。
输出:对于每组输入,要求输出一行,该行包含精确的R的n次方,输出需要去掉前导的0后不要的0,如果输出的是整数,则不要输出小数点
分析:输入比较规范,前六位是第一个数A,后面是该数的N次方,大整数的乘法可以模拟笔算乘法来做
第一步:处理输入的数A的小数点,先把小数点去掉,把原来的数存储到一个整形的数组中,记录小数点的位置,然后在开一个整数数组存储中间结果
第二步:设数组1和数组2一开始存储A,数组3是中间数组,每次由数组3来保存数组1和数组2的相乘的结果,然后把数组3赋值到数组1中,得出的结果后就是计算小数点的位置了。
第三部:这个有原来的位置就可以确定现在小数点的位置了,不过要注意的是运算过程中数组是反向的,确定小数点的位置后还要去掉前导0和后导0,这可以通过确定其起始位和终止位来输出数组1中的保存结果。
注意:输入的时候永远都是小的数在最高位
1 2 3
4 6
-------------------
6 12 18
4 8 12
*/
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
char str[10];
int n,dot;
int res[99999],a[99999],b[99999];
int la,lb;
void mul()
{
int i,j;
memset(res,0,sizeof(res));
for(i=1;i<=la;i++)
{
for(j=1;j<=lb;j++)
{
res[i+j-1]=res[i+j-1]+a[i]*b[j]; //由于乘法的特点,与下面的数进行对齐,对齐的坐标的取法就是这样的.
if(res[i+j-1]>9)
{
res[i+j]=res[i+j]+res[i+j-1]/10; //进位,由于i,j的取值是从1开始取的,所以可以直接超前进位。这里满足的是数位越高越在前面
res[i+j-1]=res[i+j-1]%10;
}
}
}
if(res[la+lb-1]>9)
{
res[la+lb]=res[la+lb]+res[la+lb-1]/10;
res[la+lb-1]=res[la+lb-1]%10;
}
la=la+lb;
for(i=1;i<=la;i++)
{
a[i]=res[i];
//cout<<a[i];
}
//cout<<endl;
}
int main()
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int up,down,i,j;
while(scanf("%s %d",str,&n)!=EOF)
{
dot=-1;
for(i=5,j=1;i>=0;i--)
{
if(str[i]!='.')
{
a[j]=b[j]=str[i]-'0';
j++;
}
//倒叙存储小数点后面的数字
else
dot=i; //dot记录小数点所在的位置,并且dot的值就是前面整数的位数
}
//for(i=1;i<=5;i++)
// cout<<a[i];
if(dot==-1)
la=lb=6;
else
la=lb=5; //含有小数点的时候数字位数就是5
for(i=1;i<n;i++) //n的值就是指数幂的值
mul();
if(dot==-1)
{
for(i=la;i>=1;i--)
cout<<a[i];
cout<<endl;
}
else
{
dot=5-dot; //因为在前面,我们使用dot判断小数点的位置,数字在没有倒叙的时候是个位数在最前面,所以,使用5-dot就可以得到小数的位数
dot=dot*n;
for(i=1;i<=la;i++)
{
if(a[i]!=0)
{
down=i;
break;
}
}
for(j=la;j>=1;j--)
{
if(a[j]!=0)
{
up=j;
break;
}
}
i=up; //i为数的最高位,j为数非零的最低位,如果最低位的j>dot,证明这个数是一个整数,所以,dot就点在dot+1的位置便可
if(up<dot) //如果i<dot,则证明这个数最后小于1,所以这个时候的小数点就要点在dot
i=dot;
j=down;
if(j>dot)
j=dot+1;
for(;i>=j;i--)
{
if(i==dot)
{
cout<<'.';
}
cout<<a[i];
}
cout<<endl;
}
}
return 0;
}
对于一个实数R(0<R<99.999),要求写程序精确计算R的n次方,其中n是整数。并且0<n<=25
输入:输入包括多组R和n,R的值占第1列到第六列,n的值占第8和第9列。
输出:对于每组输入,要求输出一行,该行包含精确的R的n次方,输出需要去掉前导的0后不要的0,如果输出的是整数,则不要输出小数点
分析:输入比较规范,前六位是第一个数A,后面是该数的N次方,大整数的乘法可以模拟笔算乘法来做
第一步:处理输入的数A的小数点,先把小数点去掉,把原来的数存储到一个整形的数组中,记录小数点的位置,然后在开一个整数数组存储中间结果
第二步:设数组1和数组2一开始存储A,数组3是中间数组,每次由数组3来保存数组1和数组2的相乘的结果,然后把数组3赋值到数组1中,得出的结果后就是计算小数点的位置了。
第三部:这个有原来的位置就可以确定现在小数点的位置了,不过要注意的是运算过程中数组是反向的,确定小数点的位置后还要去掉前导0和后导0,这可以通过确定其起始位和终止位来输出数组1中的保存结果。
注意:输入的时候永远都是小的数在最高位
1 2 3
4 6
-------------------
6 12 18
4 8 12
*/
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
char str[10];
int n,dot;
int res[99999],a[99999],b[99999];
int la,lb;
void mul()
{
int i,j;
memset(res,0,sizeof(res));
for(i=1;i<=la;i++)
{
for(j=1;j<=lb;j++)
{
res[i+j-1]=res[i+j-1]+a[i]*b[j]; //由于乘法的特点,与下面的数进行对齐,对齐的坐标的取法就是这样的.
if(res[i+j-1]>9)
{
res[i+j]=res[i+j]+res[i+j-1]/10; //进位,由于i,j的取值是从1开始取的,所以可以直接超前进位。这里满足的是数位越高越在前面
res[i+j-1]=res[i+j-1]%10;
}
}
}
if(res[la+lb-1]>9)
{
res[la+lb]=res[la+lb]+res[la+lb-1]/10;
res[la+lb-1]=res[la+lb-1]%10;
}
la=la+lb;
for(i=1;i<=la;i++)
{
a[i]=res[i];
//cout<<a[i];
}
//cout<<endl;
}
int main()
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int up,down,i,j;
while(scanf("%s %d",str,&n)!=EOF)
{
dot=-1;
for(i=5,j=1;i>=0;i--)
{
if(str[i]!='.')
{
a[j]=b[j]=str[i]-'0';
j++;
}
//倒叙存储小数点后面的数字
else
dot=i; //dot记录小数点所在的位置,并且dot的值就是前面整数的位数
}
//for(i=1;i<=5;i++)
// cout<<a[i];
if(dot==-1)
la=lb=6;
else
la=lb=5; //含有小数点的时候数字位数就是5
for(i=1;i<n;i++) //n的值就是指数幂的值
mul();
if(dot==-1)
{
for(i=la;i>=1;i--)
cout<<a[i];
cout<<endl;
}
else
{
dot=5-dot; //因为在前面,我们使用dot判断小数点的位置,数字在没有倒叙的时候是个位数在最前面,所以,使用5-dot就可以得到小数的位数
dot=dot*n;
for(i=1;i<=la;i++)
{
if(a[i]!=0)
{
down=i;
break;
}
}
for(j=la;j>=1;j--)
{
if(a[j]!=0)
{
up=j;
break;
}
}
i=up; //i为数的最高位,j为数非零的最低位,如果最低位的j>dot,证明这个数是一个整数,所以,dot就点在dot+1的位置便可
if(up<dot) //如果i<dot,则证明这个数最后小于1,所以这个时候的小数点就要点在dot
i=dot;
j=down;
if(j>dot)
j=dot+1;
for(;i>=j;i--)
{
if(i==dot)
{
cout<<'.';
}
cout<<a[i];
}
cout<<endl;
}
}
return 0;
}