CF760A Petr and a calendar 题解

Content

输入两个数 \(m,d\),请输出 \(2017\)\(m\) 月的日历【其中第一天是星期 \(d\)(如果 \(d=7\) 就是星期天)】需要印的列数。

格式见题目所述。

数据范围:\(1\leqslant m\leqslant 12,1\leqslant d\leqslant 7\)

Solution

你们怎么都这么麻烦啊,什么循环啊,什么讨论 \(4,5,6\) 啊,这题目不很简单就完事了吗?

首先我们可以看到,这里不需要考虑闰年,所以,我们把所有月份的天数通通用一个数组保存下来:

const int mo[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

那么这样的话就可以直接调用每个月份的天数了。那么第 \(m\) 月的天数就是 \(mo_m\)

我们又可以通过自己模拟发现,前面的一列仅有 \(7-d+1\) 天数,所以我们通过先减去第一列得到剩下的天数,也就是 \(mo_m-(7-d+1)\)

又因为后面每列有 \(7\) 天,所以我们后面需要的列数是 \(\left\lceil\dfrac{mo_m-(7-d+1)}{7}\right\rceil\),注意因为最后的一列不一定都是 \(7\) 天,所以我们需要向上取整。

所以,答案就是 \(\left\lceil\dfrac{mo_m-(7-d+1)}{7}\right\rceil+1\)

然而,既然这道题目的范围是如此之小,我们为什么不用打表做呢?很简单,就以生成答案的程序为 generator,直接生成出所有在这个数据范围里面的答案,然后直接输出结果就好了。

Code

#1

#include <cstdio>
#include <cmath>
using namespace std;

int n, m;
const int mo[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main() {
	scanf("%d%d", &n, &m); 
	printf("%d", (int)(ceil((mo[n] - (7 - m + 1)) / 7.0)) + 1);
}

#2

Generator

#include <cstdio>
#include <cmath>
using namespace std;

int n, m;
const int mo[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main() {
	printf("int ans[13][8] = {{0, 0, 0, 0, 0, 0, 0, 0}");
	for(int i = 1; i <= 12; ++i) {
		printf(", {0, ");
		for(int j = 1; j <= 7; ++j) {
			printf("%d", (int)(ceil((mo[i] - (7 - j + 1)) / 7.0)) + 1);
			if(j != 7)	printf(", ");
		}
		printf("}");
	}
	return printf("};"), 0;
}

Answer

#include <cstdio>
using namespace std;

int ans[13][8] = {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 5, 5, 5, 5, 5, 6, 6}, {0, 4, 5, 5, 5, 5, 5, 5}, {0, 5, 5, 5, 5, 5, 6, 6}, {0, 5, 5, 5, 5, 5, 5, 6}, {0, 5, 5, 5, 5, 5, 6, 6}, {0, 5, 5, 5, 5, 5, 5, 6}, {0, 5, 5, 5, 5, 5, 6, 6}, {0, 5, 5, 5, 5, 5, 6, 6}, {0, 5, 5, 5, 5, 5, 5, 6}, {0, 5, 5, 5, 5, 5, 6, 6}, {0, 5, 5, 5, 5, 5, 5, 6}, {0, 5, 5, 5, 5, 5, 6, 6}};

int n, m;

int main() {
	scanf("%d%d", &n, &m);
	return printf("%d", ans[n][m]), 0;
}
posted @ 2021-12-21 21:03  Eason_AC  阅读(48)  评论(0)    收藏  举报