题解 | #日历中的数字#
日历中的数字
https://ac.nowcoder.com/acm/problem/13584
写这篇题解的原由,看了下一般人的解法是先补0什么的操作,然后直接枚举每个月份的个位数(用取模即可),然而当时我脑子一抽,想了一下这不是一个简单的打表题吗,然后很快的冲完了代码,然后调bug调了几乎3个小时,终于调完之后,不禁想发一篇题解,因为是纯暴力,所以下文可能有一些看起来比较stupid的操作,看着乐即可(当时看到这道题,想到了某个奥赛题,似乎可以手模的,然后有了打表的思路)
思路不难,但是这种zz想法要考虑的细节极多
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string.h>
using namespace std;
typedef long long ll;
int check(int year) {
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ){
return true;
}
else return false;
}
int panduan(int shuzi,int a,int b,int c,int d) {
int sum=0;
if(a==shuzi) sum+=1;
if(b==shuzi) sum+=1;
if(c==shuzi) sum+=1;
if(d==shuzi) sum+=1;
return sum;
}
//记录闰年的每一个的月份的每一个数字的个数
int rn[15][20];
int main() {
// freopen("test.out","r",stdin);
// freopen("res2.out","w",stdout);
int nian,yue,shuzi;
//直接肉眼枚举一月份的各个数字出现的个数
rn[1][0]=43;rn[1][1]=45;rn[1][2]=13;rn[1][3]=5;rn[1][4]=3;rn[1][5]=3;
rn[1][6]=3;rn[1][7]=3;rn[1][8]=3;rn[1][9]=3;
for(int i=2;i<=12;i++){
for(int j=0;j<=9;j++) {
rn[i][j]=rn[1][j];
}
//1~9月份的0都是一样的,10月份和1月份每一个数字个数都是一样的
if(i<=9) {
//先减去1月份格外补的1,再加上自己需要加上的值
rn[i][1]-=31;rn[i][i]+=31;
if(!(i==3||i==5||i==7||i==8)) {
if(i==2) {
//因为这里考虑的闰年的情况,所以是按照29天来算的
rn[i][3]-=2;rn[i][1]-=1;rn[i][0]-=3;
rn[i][i]-=2;
}else {
rn[i][3]-=1;rn[i][1]-=1;rn[i][0]-=1;rn[i][i]-=1;
}
}
}
else {
//11,12月份格外讨论
if(i==10) {
continue;
}else if(i==11) {
rn[i][0]-=31;rn[i][1]+=30;
rn[i][3]-=1;rn[i][1]-=2;
}else if(i==12) {
rn[i][0]-=31;rn[i][2]+=31;
}
}
}
while(cin>>nian>>yue>>shuzi) {
//用来计算年份的数字
int a=nian%10,b=nian/10%10,c=nian/100%10,d=nian/1000%10;
if(check(nian)==true) {
if(!(yue==3||yue==5||yue==7||yue==8||yue==10||yue==12||yue==1)) {
if(yue!=2) printf("%d\n",rn[yue][shuzi]+panduan(shuzi,a,b,c,d)*30);
else {
printf("%d\n",rn[yue][shuzi]+panduan(shuzi,a,b,c,d)*29);
}
}
else{
printf("%d\n",rn[yue][shuzi]+panduan(shuzi,a,b,c,d)*31);
}
}else {
if(yue!=2) {
if(!(yue==3||yue==5||yue==7||yue==8||yue==10||yue==12||yue==1)) printf("%d\n",rn[yue][shuzi]+panduan(shuzi,a,b,c,d)*30);
else {
printf("%d\n",rn[yue][shuzi]+panduan(shuzi,a,b,c,d)*31);
}
}else {
if(shuzi==2) {
printf("%d\n",rn[yue][shuzi]-2+panduan(shuzi,a,b,c,d)*28);
}else if(shuzi==9||shuzi==0) {
printf("%d\n",rn[yue][shuzi]-1+panduan(shuzi,a,b,c,d)*28);
}
else {
// cout<<rn[yue][shuzi]<<endl;
printf("%d\n",rn[yue][shuzi]+panduan(shuzi,a,b,c,d)*28);
}
}
}
}
return 0;
}
//附上对拍程序,拍了我两个hour!!!
//int main() {
// srand((int)time(0));
// freopen("test.out","w",stdout);
// int i=1;
// while(i<=1000) {
// i=i+1;
// cout<<int(rand()%2000+1000)<<" "<<int(rand()%12+1)<<" "<<int(rand()%10)<<endl;
// }
// return 0;
//}