BBP Formula HDU6217

大致题意是计算Π的小数点后第n位的值。

这道题最主要的地方是bbp公式

BBP Formula HDU6217_第1张图片

圆周率每乘以一个16,就相当于把十六进制的圆周率小数点向右移动一位,移动b位就是乘以16^b,而BBP公式给出的级数,可以分解成两项关于b的函数,f1(b)给出的就是圆周率移动b位的整数部分数值,f2(b) 给出的是圆周率移动b位的小数数值,所以利用f2(b)就可以计算圆周率b项之后的数字,而不需要知道第一项f1(b)的值。

抽取第一部分

拆分

拆分之后我们就可以得到第 n 位。将式子乘上 16^n ,使得小数点往后移动 n 位。

前一项为了避免高精度可化成后一项只需将取合适值。

 

所以结果为的小数部分。

因为得到的只是小数部分,所以再乘以 16后,得到的整数部分转化成十六进制就可以啦。

代码:

#include
#include 
typedef long long LL;
using namespace std;
char out(int x) {
        if(0 <= x && x <= 9) return x + '0';
        else if(x == 10) return 'A';
        else if(x == 11) return 'B';
        else if(x == 12) return 'C';
        else if(x == 13) return 'D';
        else if(x == 14) return 'E';
        else if(x == 15) return 'F';
    }

 LL qpower(LL a, LL b, LL mod)
{
        LL res = 1;
        while(b)
        {
            if(b & 1) res = a * res % mod;
            b >>= 1;
            a = a * a % mod;
        }
        return res;
}

double bbp(int n,LL k,LL b)
{
    double val=0;int i; 
    for(i=0;i     {
        val+=(qpower(16,n-i,8*i+b) * 1.0/(8*i+b));
    
    }    
    for(i=n+1;i     {
        val+=powf(16,n-i)/(8*i+b);
    }
    return k*val;
}
int main()
{
    int t,n;
    cin>>t;
    int cas = 1;
    while(t--)
    {
        double ans = 0;
        cin>>n;
        n--;
        ans = bbp(n,4,1) - bbp(n,2,4) - bbp(n,1,5) - bbp(n,1,6);
    
        ans = ans - (int)ans;
        if(ans<0)ans+=1;
        ans*=16;
        char c;
        c=out((int)ans);
        printf("Case #%d: %d %c\n",cas++,n+1,c);
    }   
    return 0;
 } 

你可能感兴趣的:(Algorithm)