题目描述
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
输入描述:
输入一个整数N (1 ≤ N ≤ 1000000000)
输出描述:
输出一个整数,即为f(1) + f(2) + f(3).......f(N)
示例1
输入
7
输出
21
#include <string>
#include <iostream>
using namespace std;
long function(long n)
{
long sum = 0;
for (long i = 1; i <= n; i++)
{
if (i % 2 == 1)
{
sum += i;
}
}
return sum;
}
int main()
{
/*
*本题解题思路如下:
*已知1到7共7个数,求最大奇约数和,已知所有的奇数都是已知的最大奇约数,
*第一步就把奇数找出来1,3,5,7,还剩2,4,6这3个数,把他们转化为最大奇约数就是1,2,3
*第二步,找出1,3这两个奇数,还剩一个2,把他转化为最大奇约数就是1
*第三步,找出1这个奇数,所有最大奇约数都已经找出来了
*/
long n;
while (1)
{
cin >> n;
long sum = 0;
while (n != 1)
{
sum += function(n);
n = n / 2;
}
sum += 1;
cout << sum << endl;
}
return 0;
}
补充:后面看了其他的解题思路,发现有更简便的方法,
比如有1-7共7个数,第一轮奇数1,3,5,7和为16 = 4的平方, 4 = (7+1)/ 2
剩下2,4,6为1,2,3, 第二轮奇数为1,3和为4 = 2的平方, 2 = (3+1)/ 2
剩下2为1,第三轮奇数为1和为1 = 1的平方, 1 = (1+1)/ 2
是不是更简单,都不用每次遍历相加了,代码如下:
int main()
{
long n;
while (1)
{
cin >> n;
long sum = 0;
long temp = 0;
for (int i = n; i > 0; i /= 2)
{
temp = (i + 1) / 2;
sum += temp*temp;
}
cout << sum << endl;
}
return 0;
}