一【题目描述】
标题:分数
1/1 + 1/2 + 1/4 + 1/8 + 1/16 + ....
每项是前一项的一半,如果一共有20项,
求这个和是多少,结果用分数表示出来。
类似:
3/2
当然,这只是加了前2项而已。分子分母要求互质。
注意:
需要提交的是已经约分过的分数,中间任何位置不能含有空格。
请不要填写任何多余的文字或符号。
二【解题思路】
额,这个没有什么好说的,一看就知道是等差数列求和,然后公比是1/2。一般前面的小题都会有一些数学数列的知识,所以这里我把等差数列和等比数列的通项公式和求和公式展示出来回忆一下。
等比数列通项公式:
等比数列求和公式:
等差数列通项公式:
等差数列求和公式:
等差数列求和公式:
三【解题步骤】
所以我们直接带入a1=1,q=1/2,n=20,那么结果就是:2-(1/2)^19,把它转换为(2^20-1)/2^19,我们计算出这整数,然后把数字带进去求最大公约数,最后化简。我用程序得到了1048576/524288,这题很巧,就是互素的。
那么最简单的程序不就是这样的吗?
#include<iostream>
#include<math.h>
using namespace std;
int gcd(int a,int b)
{
if(a%b==0) return b;
return gcd(b,a%b);
}
int main(void)
{
int a,b,c;
a = pow(2,20)-1;
b = pow(2,19);
c = gcd(a,b);
a = a/c;
b = b/c;
cout<<a<<"/"<<b<<endl;
return 0;
}
上面我们使用pow自带的库函数来求2的几次方,但是如果数据很大的话,这个时间复杂度有O(N),所以这里介绍快速幂方法,将时间复杂度变到O(longN),这里只有一个参数,你可以自己添加参数,实现pow(a,b)。
#include<iostream>
using namespace std;
//快速幂运算
long pow_2(int b)
{
long x = 2;
long res = 1;
while(b>0){
if(b&1)//指数的二进制位和1进行与运算,这样就将累乘次数减少,从而达到优化
res*=x;
b>>=1;//右移一位
x = x*x;
}
return res;
}
//最大公约数
int gcd(long a,long b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int main(void)
{
cout<<gcd(pow_2(20)-1,pow_2(19))<<endl;
cout<<pow_2(20)-1<<"/"<<pow_2(19)<<endl;
return 0;
}
不管怎样,你都会得到答案:1048575/524288
四【总结】
数学知识还是很重要的呀,如果是答题还要学会优化哦。如有更好的解答,欢迎交流哦,谢谢。