BBP Formula HDU6217

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

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

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

抽取第一部分

拆分

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

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

 

所以结果为的小数部分。

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

代码:

#include<iostream>
#include<math.h> 
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<n+1;i++)
    {
        val+=(qpower(16,n-i,8*i+b) * 1.0/(8*i+b));
    
    }    
    for(i=n+1;i<n+1000+1;i++)     //此处无穷大取多1000
    {
        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;
 } 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值