专栏文章
题解:P14042 [SDCPC 2019] Calandar
P14042题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minvmo15
- 此快照首次捕获于
- 2025/12/02 09:05 3 个月前
- 此快照最后确认于
- 2025/12/02 09:05 3 个月前
题意
给定两个年月日日期以及第一个日期的星期数,求第二个年月日是星期几。( 天一个月,一周五天)
思路
求第二个日期的星期数,需要先求出两个日期之间相差的天数,然后用天数对 取模求出星期数。
如果考虑暴力,从第一个日期开始往后算,由于年份最大为 ,所以超时的风险很大。
事实上,想要计算相差的天数可以简化计算过程:
- 对于月份相同的两个日期,相差的天数即为 。
- 对于月份不同但年份相同的两个日期,可以先计算两个月之间度过了完整一个月的月份数为 ,将这个数乘 就是这几个月度过的天数。再将两端点月份剩下的天数加起来,左端点月份度过的天数为 ,右端点月份度过的天数为 。因此总天数为 。
- 对于年份不同的两个日期,先算度过了完整的年份数为 ,由于一年有 天,所以该数乘 即这几年度过的天数。再算两端点年份中度过完整月份的月份数,左端点完整月份数为 ,右端点完整月份数为 ,总共就是 ,再按上述同理算出剩下的天数。因此总天数为 。
算完天数,将当前星期数加上天数,对 取模,即可得到最终的星期数。
但还没完,我们观察样例发现有下面这样的数据:
CPP1000000000 1 1 Wednesday
2019 5 12
前面的日期要比后面的日期要晚,想解决也很简单,首先判断年份是否晚于后者,如果年份相同那么判断月份,月份相同再判断天数即可。
如果前者晚于后者,可以使用
swap 函数将年月日两个数据交换。同时还要注意,我们最后算星期数的时候还需要从晚到早数,因此算出的天数之差需要取相反数再取模。Code
CPP#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
using namespace std;
typedef long long ll;
ll t, y1, m1, d1, y2, m2, d2, del, wkn;
string wk;
bool checkswp(){ // 检查日期是否需要交换
if(y1 > y2) return true;
if(y1 == y2 && m1 > m2) return true;
if(y1 == y2 && m1 == m2 && d1 > d2) return true;
return false;
}
void swp(){ // 交换日期
swap(y1, y2);
swap(m1, m2);
swap(d1, d2);
return ;
}
ll gabs(ll x){ // 获取取模结果
return ((x >= 0LL) ? x : (x + 5)); // 负数取模需要加上除数
}
int main()
{
scanf("%lld", &t);
while(t--){
scanf("%lld%lld%lld", &y1, &m1, &d1);
cin >> wk;
// 获取日期
if(wk == "Monday") wkn = 0LL;
else if(wk == "Tuesday") wkn = 1LL;
else if(wk == "Wednesday") wkn = 2LL;
else if(wk == "Thursday") wkn = 3LL;
else if(wk == "Friday") wkn = 4LL;
scanf("%lld%lld%lld", &y2, &m2, &d2);
// 交换日期
bool ifswp = checkswp();
if(ifswp) swp();
// 求差值
if(m1 == m2) del = d2 - d1;
else{
ll tmp;
if(y1 == y2) tmp = (m2 - m1 - 1LL) * 30LL;
else tmp = (10 - m1 + m2) * 30LL + (y2 - y1 - 1LL) * 360LL;
del = d2 + 30LL - d1 + tmp;
}
if(ifswp) del = -del;
wkn = gabs((wkn + del) % 5LL); // 计算日期
// 输出
switch(wkn){
case 0LL:
puts("Monday");
break;
case 1LL:
puts("Tuesday");
break;
case 2LL:
puts("Wednesday");
break;
case 3LL:
puts("Thursday");
break;
case 4LL:
puts("Friday");
break;
}
}
return 0; // 结束 (。・ω・。)
}
/*
你好啊,我是 vzAczA。
趁 UNNN 不在,我把这个代码修改了一下。
因此你是不能通过复制粘贴这个代码来通过本题的。
祝你好运^ ^
*/
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...