【GDOI2022PJD2T3 教室的电子钟】题解
D2T3 教室的电子钟
题目
为了迎接 GDOI,小蒟蒻学校所有教室的钟都换成了电子钟。电子钟会显示年月日时分秒的信息,每天的时间从 00:00:00 到 23:59:59。电子钟共有 14 个格子,共 14 × 7 = 98 个 LED 灯管组成。
具体来说,每个格子都是下面的十种状态中的一种,可以看到每个数字都是有 7 个 LED 灯管的亮暗状态呈现的:
这个钟的设计非常奇怪,每个灯管保持亮和保持暗的时候都是不消耗电的,每当由暗变成亮或者由亮变成暗则要消耗 1 个单位的电。小蒟蒻想知道,在需要考虑平闰年的真实情况下,从 \(X\) 年 \(Y\) 月 \(Z\) 到 \(A\) 时 \(B\) 分 \(C\) 秒起,到 \(X′\) 年 \(Y ′\) 月 \(Z′\) 日到 \(A′\) 时 \(B′\) 分 \(C′\) 秒一共消耗了多少单位的电。
为了解决这道题,小蒟蒻想向你介绍一些他在科学课上学到的知识。
对于平年来说,每个月对应的天数如下:
对于闰年来说,每个月对应的天数如下:
其中闰年指的是年份能被 4 整除且不能被 100 整除,或者能被 400 整除的年份。平年则是不是闰年的年份。例如 2020 年是闰年,1900 年不是闰年。
思路
对于前70分,暴力模拟即可。
我们先弄出一个 \(10 \times 10\) 的表格,分别代表每个数字变成另一个数字所需要的代价,然后一秒一秒跳。
对于后30分,我们可以把年和后面的分开。先预处理平年和闰年情况变为常量,然后每一年分类讨论即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'
){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x
<<3)+(ch^48);ch=getchar();}return x*f;}
//#define N
//#define M
//#define mo
int n, m, i, j, k, T;
int mp[10]={6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
int b[10][10]=
{
0, 4, 3, 3, 4, 3, 2, 3, 1, 2,
4, 0, 5, 3, 2, 5, 6, 1, 5, 4,
3, 5, 0, 2, 5, 4, 3, 4, 2, 3,
3, 3, 2, 0, 3, 2, 3, 2, 2, 1,
4, 2, 5, 3, 0, 3, 4, 3, 3, 2,
3, 5, 4, 2, 3, 0, 1, 4, 2, 1,
2, 6, 3, 3, 4, 1, 0, 5, 1, 2,
3, 1, 4, 2, 3, 4, 5, 0, 4, 3,
1, 5, 2, 2, 3, 2, 1, 4, 0, 1,
2, 4, 3, 1, 2, 1, 2, 3, 1, 0
};
int mth[15]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0, 0};
int n1, yu1, r1, s1, f1, m1;
int n2, yu2, r2, s2, f2, m2;
int ans=0;
const int ping_nian=106904682;
const int run_nian=107197568;
void bian(int x, int y, int z)
{
int sum=0;
// printf("%lld->%lld: ", x, y);
while(z--) sum+=b[x%10][y%10], x/=10, y/=10;
// printf("%lld\n", sum);
ans+=sum;
}
int pan(int x)
{
if(x%400==0) return 1;
if(x%100==0) return 0;
if(x%4==0) return 1;
return 0;
}
int cong()
{
while(n1!=n2 || yu1!=yu2 || r1!=r2 || s1!=s2 || f1!=f2 || m1!=m2)
{
if(m1<59) bian(m1, m1+1, 2), ++m1;
else
{
bian(m1, 0, 2); m1=0;
if(f1<59) bian(f1, f1+1, 2), ++f1;
else
{
bian(f1, 0, 2); f1=0;
if(s1<23) bian(s1, s1+1, 2), ++s1;
else
{
bian(s1, 0, 2); s1=0;
if(r1<(yu1==2 ? (pan(n1) ? 29 : 28) : mth[yu1])) bian(r1, r1+1, 2), ++r1;
else
{
bian(r1, 1, 2); r1=1;
if(yu1<12) bian(yu1, yu1+1, 2), ++yu1;
else
{
bian(yu1, 1, 2); yu1=1;
bian(n1, n1+1, 4); ++n1;
}
}
}
}
}
}
return ans;
}
void zhuan()
{
while(n1+1<n2)
{
if(pan(n1))
{
if(yu1<2) ans+=run_nian;
else if(yu1==2 && r1<29) ans+=run_nian;
else ans+=ping_nian;
}
else if(pan(n1+1))
{
if(yu1<2) ans+=ping_nian;
else if(yu1==2 && r1<29) ans+=ping_nian;
else ans+=run_nian;
}
else ans+=ping_nian;
bian(n1, n1+1, 4), ++n1;
}
}
signed main()
{
// 107197568
// printf("%lld\n", qiu());
scanf("%lld%lld%lld%lld%lld%lld", &n1, &yu1, &r1, &s1, &f1, &m1);
scanf("%lld%lld%lld%lld%lld%lld", &n2, &yu2, &r2, &s2, &f2, &m2);
zhuan();
printf("%lld", cong());
// printf("%lld", qiu());
return 0;
}
总结
细节处理题。
对于做日历类的数据处理题的时候,有几点需要注意:
- 平年闰年在什么时候
- 2月前和2月后该算成哪一年
对于电子钟类题目,要注意是求的是变化还是亮的个数。
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/16191355.html