hdu 6217

In 1995, Simon Plouffe discovered a special summation style for some constants. Two year later, together with the paper of Bailey and Borwien published, this summation style was named as the Bailey-Borwein-Plouffe formula.Meanwhile a sensational formula appeared. That is
π=∑k=0∞116k(48k+1−28k+4−18k+5−18k+6)

For centuries it had been assumed that there was no way to compute the n-th digit of π without calculating allof the preceding n - 1 digits, but the discovery of this formula laid out the possibility. This problem asks you to
calculate the hexadecimal digit n of π immediately after the hexadecimal point. For example, the hexadecimalformat of n is 3.243F6A8885A308D313198A2E … and the 1-st digit is 2, the 11-th one is A and the 15-th one is D.

Input
The first line of input contains an integer T (1 ≤ T ≤ 32) which is the total number of test cases.
Each of the following lines contains an integer n (1 ≤ n ≤ 100000).

Output
For each test case, output a single line beginning with the sign of the test case. Then output the integer n, andthe answer which should be a character in {0, 1, · · · , 9, A, B, C, D, E, F} as a hexadecimal number

Sample Input
5
1
11
111
1111
11111

Sample Output
Case #1: 1 2
Case #2: 11 A
Case #3: 111 D
Case #4: 1111 A
Case #5: 11111 E
题意:用给的公式求π的第i位。
做法:最开始我想用大数模拟,但是发现16^1e5太大了,跑的很慢,然后我发现对于第i位,前i的精度肯定是足够的,如果求第i为,先把所有的项的乘以16^n,然后就对于给出的四个公式一个一个的来处理,对于第i位的第1个公式,可知(16^(n-k))/(8*i+1) 大于16的部分不会对这一项造成影响,然后用快速幂算出16^(n-k)%(16*(8*i+1));就只有这部分会对结果造成影响,然后然后把这样的值统计起来,最后对16取余就是答案了。因为会有小数,小数加起来会造成影响,所以保存商的和,最后对16进行取模就可以了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll qpow(int x,int b,int m){
    ll sum = 1;
    ll now = x;
    while(b){
        if(b&1) sum = sum*now%m;
        now = now*now%m;
        b >>= 1;
    }
    return sum;
}
void add(int &x,int y){
    x += y;
    if(x >= 16) x -= 16;
    if(x < 0) x += 16;
}
char change(int x){
    if(x < 10) return x+'0';
    return x-10+'A';
}
int main(){

    int T;
    cin >> T;
    int kcase = 1;
    while(T--){
        int n;
        scanf("%d",&n);
        double  cnt = 0;
        for(int i = 0;i <= n;i ++){
            double now = qpow(16,n-i,16*(8*i+1));
            cnt += now*4/(8*i+1);
            now = qpow(16,n-i,16*(8*i+4));
            cnt -= now*2/(8*i+4);
            now= qpow(16,n-i,16*(8*i+5));
            cnt -= now/(8*i+5);
            now = qpow(16,n-i,16*(8*i+6));
            cnt -= now/(8*i+6);
        }
        int ans = floor(cnt);
        ans = (ans%16+16)%16;
        printf("Case #%d: %d %c\n",kcase++,n,change(ans));
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/78697626