CF760A Petr and a calendar 題解
阿新 • • 發佈:2021-12-21
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;
}