最后过的一道题,看队友的样子,貌似是神烦的题
2800年一循环,菜勒公式可以搞
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
long long sum[2801][13];
void init()
{
memset(sum,0,sizeof(sum));
long long count=0;
for(int i=1;i<=2800;i++)
{
for(int j=1;j<=12;j++)
{
int y,m,d;
y=2016+i-1;
m=j;
if(m==1)
{
y=y-1;
m=13;
}
else if(m==2)
{
y=y-1;
m=14;
}
if((1 + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7==0)
{
sum[i][j]=count+7;
count+=7;
}
else
sum[i][j]=count;
}
}
// printf("%lld\n",sum[2800][12]);
return;
}
long long F(long long y,long long m,long long d)
{
long long ans=0;
ans+=(y-2016)/2800*sum[2800][12];
//printf("%lld\n",ans);
long long tmp=y;
tmp=(tmp-2016)%2800+2016;
if(m>1)
ans+=(sum[tmp-2016+1][m-1]);
else if(m==1&&tmp>2016)
ans+=(sum[tmp-2016][12]);
//printf("%d %d\n",tmp-2016+1,m-1);
// printf("%lld\n",sum[tmp-2016+1][m-1]);
if(m==1)
{
y-=1;
m=13;
}
else if(m==2)
{
y-=1;
m=14;
}
for(long long i=1;i<=d;i++)
{
if((i + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7==i-1)
ans++;
}
// printf("%d\n",ans);
return ans;
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
long long x1,y1,z1,x2,y2,z2;
scanf("%lld%lld%lld%lld%lld%lld",&x1,&y1,&z1,&x2,&y2,&z2);
long long ans1=F(x1,y1,z1);
long long ans2=F(x2,y2,z2);
long long ans=ans2-ans1;
//printf("%lld\n",ans);
if(y1==1)
{
y1=13;
x1-=1;
}
else if(y1==2)
{
x1-=1;
y1=14;
}
if((z1 + 2*y1 + 3*(y1+1)/5 + x1 + x1/4 - x1/100 + x1/400) % 7==z1-1)
ans++;
printf("%lld\n",ans);
}
}

本文介绍了一种解决特定日期问题的方法,利用2800年的周期性和菜勒公式,通过预处理和查找表的方式快速计算指定日期范围内特定类型日子的数量。代码使用C++实现。
563

被折叠的 条评论
为什么被折叠?



