引用:
Time Limit: 500MS | Memory Limit: 10000K | |
Total Submissions: 67973 | Accepted: 15908 |
Description
This problem requires that you write a program to compute the exact value of R n where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.
Input
Output
Sample Input
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201
Hint
s is a string and n is an integer
C++
while(cin>>s>>n)
{
...
}
c
while(scanf("%s%d",s,&n)==2) //to see if the scanf read in as many items as you want
/*while(scanf(%s%d",s,&n)!=EOF) //this also work */
{
...
}
分析:
题目要求输入实数R,范围0.0~99.999,有效数字5位。幂指数n,范围0~25,整数.
难点在于乘法计算过程中,float型实数最大只有3.4E +/- 38 (7 digits)。不可能作为结果,数据会溢出。
对策:把乘数、被乘数拆为只有1位的整数,存入分配的整形数组。
我的代码(作参考,可实现目标。未测试"计算优化")
#include <conio.h>
#include <iostream>
using namespace std;
struct R_Input
{
float R;
int n;
struct R_Input* next;
};
//申明函数
int Add(int* R, int num); //*R,num 0-9
void Cal(R_Input* rTail);
int main()
{
cout<<"R:0.0000<R<99.999 and n:0<n<=25"
<<"/nInput any character excluding number to quit."<<endl;
//input data
float R_In=0;
int n=0;
R_Input R_cin;
R_Input* rTail;
cin>>R_In>>n;
R_cin.R=R_In;
R_cin.n=n;
R_cin.next=NULL;
rTail=&R_cin;
while(cin>>R_In>>n)
{
R_Input* s=new R_Input;
s->R=R_In;
s->n=n;
s->next=NULL;
rTail->next=s;
rTail=s;
}
//计算
rTail=&R_cin;
cout<<"Sample Output"<<endl;
while(rTail)
{
Cal(rTail);
rTail=rTail->next;
}
_getch();
return 0;
}
int Add(int* R, int num)
{
int m,res;
m=*R;
res=m+num;
if(res<10) *R=res;
else
{
*R=res%10;
Add(R+1,res/10);
return 1;
}
return 0;
}
const int SPACE=256;
void Cal(R_Input* rTail)
{
int ans[SPACE]={0};
int lenInt,lenDec;
//输入实数R
if(1)
{
int k=(int)rTail->R;
int l=(int)((rTail->R-k)*10000);
for(int i=1;i<5;ans[i-1]=l%10,l=l/10,i++);
l=(int)((rTail->R-k)*100000);
if((l-l/10*10)!=0) Add(ans,1);
for(int i=4;i<=5;ans[i]=k%10,k=k/10,i++);
}
//幂运算
int multiplier[6];
multiplier[0]=ans[0];
multiplier[1]=ans[1];
multiplier[2]=ans[2];
multiplier[3]=ans[3];
multiplier[4]=ans[4];
multiplier[5]=ans[5];
int Exp=rTail->n;
while(Exp>1)
{
int An[256];
for(int i=0;i<256;i++)
{
An[i]=ans[i];
ans[i]=0;
}
int len;
for(len=SPACE-1;!An[len];len--);
for(int i=0;i<=len;i++)
for(int j=0;j<6;j++)
{
int A,B,Mi,Mj,Ex10;
for(Mi=1;Mi<=i;Mi++);
for(Mj=1;Mj<=j;Mj++);
//计算A*B
Ex10=Mi+Mj-2;
A=An[i];
B=multiplier[j];
if(A*B!=0)
Add(&ans[Ex10],A*B);
}
Exp--;
}
char ch[SPACE]={0};
int where_0;
for(where_0=SPACE-1;ans[where_0]==0 && where_0>0;where_0--);
//获取小数、整数部分数位
lenDec=4*rTail->n;
lenInt=where_0-lenDec+1;
int prt_n=where_0;
int chEnd=0;
for(;lenInt>0;prt_n--,lenInt--)
{
// printf("%d",ans[prt_n]);
sprintf(&ch[chEnd++],"%d",ans[prt_n]);
}
// printf(".");
if(lenInt<0)
{
sprintf(&ch[chEnd++],"0");
prt_n=prt_n-lenInt;
}
sprintf(&ch[chEnd++],".");
for(;prt_n>=0;prt_n--)
{
// printf("%d",ans[prt_n]);
sprintf(&ch[chEnd++],"%d",ans[prt_n]);
}
// printf("/n");
for(chEnd--;chEnd>=0 && ch[chEnd]=='0';chEnd--);
ch[chEnd+1]='/0';
cout<<ch<<endl;
}