这么大数的乘法、除法运算,肯定不能先全部乘起来,我的思路是计算出分子、分母上的每个数的个数(因为最大的数为10000,可以开一个数组记录个数)。
利用了随机数方法终于知道错在哪了,中间如果出现连乘还是会溢出,这点没想到,以下是我的溢出代码:
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<time.h>
using namespace std;
int up[10005];
int main()
{
srand(time(NULL));
// freopen("out.txt","w",stdout);
int p,q,r,s;
while(cin>>p>>q>>r>>s)
{
memset(up,0,sizeof(up));
double sum = 1;
int t1 = r - s,t2 = p - q;
for(int i = 2;i <= p;i++)
up[i]++;
for(int i = 2;i <= s;i++)
up[i]++;
for(int i = 2;i <= t1;i++)
up[i]++;
for(int i = 2;i <= q;i++)
up[i]--;
for(int i = 2;i <= r;i++)
up[i]--;
for(int i = 2;i <= t2;i++)
up[i]--;
for(int i = 2;i <= 10000;i++)
{
if(up[i] > 0) sum *= pow(i,up[i]);
if(up[i] < 0) sum /= pow(i,-up[i]);
}
printf("%.5lf\n",sum);
}
return 0;
}
以下是我自己改的代码AC的,我强制要求乘法、除法交替运行:
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<time.h>
using namespace std;
int up[10005];
int main()
{
// freopen("out.txt","w",stdout);
int p,q,r,s;
while(cin>>p>>q>>r>>s)
{
int cheng = 2,chu = 2;
memset(up,0,sizeof(up));
double sum = 1;
int t1 = r - s,t2 = p - q;
for(int i = 2;i <= p;i++)
up[i]++;
for(int i = 2;i <= s;i++)
up[i]++;
for(int i = 2;i <= t1;i++)
up[i]++;
for(int i = 2;i <= q;i++)
up[i]--;
for(int i = 2;i <= r;i++)
up[i]--;
for(int i = 2;i <= t2;i++)
up[i]--;
while(1)
{
int flag = 1;
for(int i = 2;i <=10000;i++)
if(up[i]) {flag = 0;break;}
if(flag) break;
for(int i = cheng;i <= 10000;i++) //乘法
if(up[i] > 0)
{
sum *= pow(i,up[i]);
up[i] = 0;
cheng = i + 1;
break;
}
for(int i = chu;i <= 10000;i++) //除法
if(up[i] < 0)
{
sum /= pow(i,-up[i]);
up[i] = 0;
chu = i + 1;
break;
}
}
printf("%.5lf\n",sum);
}
return 0;
}
LRJ的思路是先求出10000以内所有的素数,通过分解素数来计算,他的算法可以说比我的循环少很多,更不容易超时。