ZOJ - 3939 The Lucky Week【简单方法】
程序员文章站
2022-07-15 16:16:55
...
题目
Sample Input
2
2016 4 11 2
2016 1 11 10
Sample Output
2016 7 11
2017 9 11
题意:t组数据,给出四个数,x,y,z,m,其中 x,y,z,分别是第一个幸运日的年月日,幸运日的定义为每月的1,11,或21,号且星期一,问第m个幸运日的年月日
注意第一个幸运日的范围为(1753 1.1~9999 12 .31)并不是要求的所有幸运日都在这个范围内
思路:暴力的话,1e9肯定超时,我们可以找下规律,我们发现从第一个幸运日开始到400年之后的同样的月份和日期例从2016 4 11 ~2416 4 11 总共有2059个幸运日,每个幸运日都符合这个规律,这样的话我们直接看要求的是第几个,把它减一,看他里面有几个2058,同时年份加上400,最后一个一个寻找,具体看代码(实力有限,大佬勿喷)
AC code
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
using namespace std;
int t,x,y,z,m;
int a[2][14]={{0,31,29,31,30,31,30,31,31,30,31,30,31},{0,31,28,31,30,31,30,31,31,30,31,30,31}};//a[0]闰年,a[1]平年
void solve()
{
m--;
int p,s=0;
int k=m/2058;//1~2059这点一定要注意除上2058
m-=k*2058;
x+=400*k;
while(s<m)
{
if(((x%4==0)&&(x%100!=0))||(x%400==0))p=0;//判断是否闰年
else p=1;
z+=7;//保证每次都是星期一
if(z>a[p][y])
{
z-=a[p][y];
y++;//下一月
if(y>12)
{
y-=12;
x++;//下一年
}
}
if(z==1||z==11||z==21)
{
s++;
}
}
printf("%d %d %d\n",x,y,z);
}
int main()
{
ios::sync_with_stdio(0);
cin>>t;
while(t--)
{
cin>>x>>y>>z>>m;
solve();
}
}
一直不知道该除以几,推了一大会儿1~2059除以2058,对于星期周期,1—8除以7
例如第一天星期1,问第8天星期几,,8-1,7-7*7/7=0,是星期1,我真是太菜了…,大佬有任何关于周期好的技巧和方法,欢迎在下方评论qaq;