题目背景
《爱与愁的故事第二弹·compute》第一章。
题目描述
中秋至,博饼声铿锵不断。爱与愁大神兴致勃勃地到学校博饼,结果抱回家的只有一秀二举。爱与愁大神十分生气,打电话给月落乌啼:“喂,帮我算出圆周率小数点后n(n<=10000)位,速度……”然后就挂了电话,也不知道月落乌啼正准备去上课。月落乌啼只好请到了你,让你编一个程序求出圆周率小数点后n位。
输入格式
只有一行:n
输出格式
若干行。
第一行:3.
第二行开始:圆周率的小数部分。10个数一个空格,50个数一次回车。
输入输出样例
输入 #1复制
100
输出 #1复制
3.
1415926535 8979323846 2643383279 5028841971 6939937510
5820974944 5923078164 0628620899 8628034825 3421170679
说明/提示
对于 30%30% 的数据,n\leq 10^3n≤10
3
。
对于 100%100% 的数据,n\leq 10^4n≤10
4
。
时限:1\sim 61∼6 点 11 秒,77 点 33 秒,88 点 88 秒,9\sim 109∼10 点 1212 秒。
上代码:
#include<cstdio>
using namespace std;
struct df
{
long long num[1011];
int head;
int tail;
};
int n=0;
df pi={},a={},b={};
void out(df a)
{
printf("%lld.\n",a.num[0]);
for(int i=1;i<=n/10;i++)
{
printf("%010lld",a.num[i]);
if(i%5==0)printf("\n");
else printf(" ");
}
switch(n%10)
{
case 0:printf("");break;
case 1:printf("%01lld",a.num[n/10+1]/1000000000ll);break;
case 2:printf("%02lld",a.num[n/10+1]/100000000ll);break;
case 3:printf("%03lld",a.num[n/10+1]/10000000ll);break;
case 4:printf("%04lld",a.num[n/10+1]/1000000ll);break;
case 5:printf("%05lld",a.num[n/10+1]/100000ll);break;
case 6:printf("%06lld",a.num[n/10+1]/10000ll);break;
case 7:printf("%07lld",a.num[n/10+1]/1000ll);break;
case 8:printf("%08lld",a.num[n/10+1]/100ll);break;
case 9:printf("%09lld",a.num[n/10+1]/10ll);break;
}
if(n%50)printf("\n");
return;
}
df plus(df a,df b)
{
df c={};
long long t=0;
bool zero=true;
c.tail=a.tail>b.tail?a.tail:b.tail;
c.head=(a.head<b.head?a.head:b.head)-1;
if(c.head<0)c.head=0;
for(int i=c.tail;i>=c.head;i--)
{
c.num[i]=a.num[i]+b.num[i]+t;
if(c.num[i])zero=false;
t=c.num[i]/10000000000ll;
c.num[i]%=10000000000ll;
}
if(zero)
{
c.head=c.tail;
return c;
}
while(c.num[c.head]==0)c.head++;
while(c.num[c.tail]==0)c.tail--;
return c;
}
df minus(df a,df b)
{
df c={};
long long t=0;
bool zero=true;
c.tail=a.tail>b.tail?a.tail:b.tail;
c.head=a.head<b.head?a.head:b.head;
for(int i=c.tail;i>=c.head;i--)
{
c.num[i]=a.num[i]-b.num[i]+t;
if(c.num[i])zero=false;
if(c.num[i]<0)
{
c.num[i]+=10000000000ll;
t=-1;
}
else
t=0;
}
if(zero)
{
c.head=c.tail;
return c;
}
while(c.num[c.head]==0)c.head++;
while(c.num[c.tail]==0)c.tail--;
return c;
}
df divided(df a,long long b)
{
df c={};
long long t=0;
bool zero=true;
c.head=a.head;
c.tail=a.tail;
for(int i=c.head;i<=c.tail;i++)
{
c.num[i]=(a.num[i]+t)/b;
if(c.num[i])zero=false;
t=(a.num[i]+t)%b*10000000000ll;
if(t&&i==c.tail&&c.tail<n/10+10)c.tail++;
}
if(zero)
{
c.head=c.tail;
return c;
}
while(c.num[c.head]==0)c.head++;
return c;
}
void set()
{
a.num[0]=16ll,a.head=0,a.tail=0;
b.num[0]=4ll,b.head=0,b.tail=0;
a=divided(a,5);
b=divided(b,239);
return;
}
int main()
{
scanf("%d",&n);
set();
long long i=1;
while(a.head!=n/10+10)
{
pi=plus(pi,divided(a,i));
pi=minus(pi,divided(b,i));
a=divided(a,25);
b=divided(b,57121);
i+=2;
pi=minus(pi,divided(a,i));
pi=plus(pi,divided(b,i));
a=divided(a,25);
b=divided(b,57121);
i+=2;
}
out(pi);
return 0;
}