1. 程式人生 > 其它 >CF760A Petr and a calendar 題解

CF760A Petr and a calendar 題解

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;
}