Harmonic Number (II)

来源:互联网 发布:淘宝服装试用报告范文 编辑:程序博客网 时间:2024/05/18 11:22

I was trying to solve problem ‘1234 - Harmonic Number’, I wrote the following code

long long H( int n ) {
long long res = 0;
for( int i = 1; i <= n; i++ )
res = res + n / i;
return res;
}

Yes, my error was that I was using the integer divisions only. However, you are given n, you have to find H(n) as in my code.

Input
Input starts with an integer T (≤ 1000), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n < 231).

Output
For each case, print the case number and H(n) calculated by the code.

Sample Input
11
1
2
3
4
5
6
7
8
9
10
2147483647
Sample Output
Case 1: 1
Case 2: 3
Case 3: 5
Case 4: 8
Case 5: 10
Case 6: 14
Case 7: 16
Case 8: 20
Case 9: 23
Case 10: 27
Case 11: 46475828386

题意:

让你用求h(n);

思路:暴力的话会超时,所以我们就要找规律看看,你会发现假设 tmp 是 n/i 的值,当n == 10的时候(取具体值)

当 tmp = 1 时,个数 是10/1 - 10/2 == 5个

当 tmp = 2 时,个数 是10/2 - 10/3 == 2个

当 tmp = 3 时,个数 是10/3 - 10/4 == 1个
…………
当 tmp = 10时,个数是10/10 - 10/11 == 1个
所以我们发现有个规律了,当tmp == i 的时候,我们要求的个数就是 10/i - 10/(i+1),然后我们前1 — sqrt(n)个数的数值还是比较大的,但是数据范围变小了
暴力可以求出来(从1到sqrt(n)算出n/i>=sqrt(n)的情况),剩下的 sqrt(n)+1 — n个数中 数据范围还是比较大,但是 n/i 的数据范围介于 1 - sqrt(n)之间,所以用我们找出的规律可以求出来
#include<stdio.h>#include<string.h>#include<math.h>int main(){    int t;    scanf("%d",&t);    int g=0;    while(t--)    {        ++g;        int n;        scanf("%d",&n);        int m=sqrt(n);        long long int sum=0;        for(int i=1;i<=m;i++)        {             sum+=n/i;        }            for(int temp=1;temp<=m;temp++)                sum+=temp*((n/temp)-(n/(temp+1)));            if(m==n/m)                sum-=m;            printf("Case %d: %lld\n",g,sum);    }}

0 0