点我补题 (需要更换)
A.九九八十一难 思路 01背包。尝试将每一种物品放入背包中,检查容积是否刚好为 $sum / 2$ 即可。
Fun Fact:验题人一开始用错解卡过了样例,然后出题人进行了紧急(并不)加强。
代码(验题程序) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void solve () { int n; cin >> n; vector<int > vec (n) ; for (auto &v : vec) cin >> v; int tgt = accumulate (all (vec), 0 ); if (tgt & 1 ) { cout << "No" << endl; return ; } tgt /= 2 ; constexpr int MAX = 100 * 200 + 10 ; vector<int > dp (MAX, 0 ) ; dp[0 ] = 1 ; for (auto &v : vec) for (int i = MAX - 1 ; i >= 0 ; i--) if (dp[i]) dp[i + v]++; cout << (dp[tgt] ? "Yes" : "No" ) << endl; }
B.眼看喜 思路 似乎是纯模拟题。本题所采用的技巧((l)++,(r+1)–)可以在多种类型的题目(比如CF2014D 或者各种括号序列题)见到。比较重要。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void solve () { int x, m; cin >> x >> m; vector<int > vec (x + 10 , 0 ) ; while (m--) { int l, r; cin >> l >> r; vec[l] += 1 , vec[r + 1 ] -= 1 ; } int ans = (vec[0 ] == 0 ); for (int i = 1 ; i <= x; i++) { vec[i] += vec[i - 1 ], ans += !vec[i]; } cout << ans << endl; }
C.耳听怒 出题人说自己有严格的数学证明。怎么证的问他去。
反正手玩一下可以发现在 $n \times n $ 的大前提下,后手似乎必胜。那就猜后手必胜交一发吧。
嘿,后手确实必胜。
代码(Python)
D.鼻嗅爱 思路 实际技巧和B题相同。
对于每个位置,记录其最远能走到的位置的方法就是将其最远位置+1的格子的格子减去1,然后一轮遍历下来看看第 $n$ 个格子有没有办法可以到达即可。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void solve () { int n; cin >> n; vector<int > c (n + 2 ) ; for (int i = 1 ; i <= n; i ++ ){ int x; cin >> x; c[i] += c[i - 1 ]; if (c[i] || i == 1 ){ c[i] += 1 ; c[min (n, i + x) + 1 ] -= 1 ; } } cout << (c[n] ? "Yes" : "No" )<<endl; }
E.舌尝思 思路 Python秒了
C++有两种方案,一种是题目提示里给出的求数位和相加模9是否为0并且奇数和与偶数和只差模11是否为0。
另一种是模拟竖式除法直接一步一步取模。
按需取用。
代码(思路2) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int divMod (string str, int num) { int s = 0 ; for (auto &ch : str) s = (s * 10 + ch - '0' ) % num; return s; } void solve () { int n; cin >> n; int ans = 0 ; while (n--) { string str; cin >> str; ans += (divMod (str, 99 ) == 0 ); } cout << ans << endl; }
代码(Python) 1 2 3 4 5 6 import syssys.set_int_max_str_digits(10000 ) ans = 0 for _ in range (int (input ())): ans += (int (input ()) % 99 == 0 ) print (ans)
F.身本忧 思路 很签的模拟吧,基本上样例过了就不会出错的那种。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void solve () { int n, m; cin >> n >> m; vector<string> vec (n) ; for (auto &s : vec) cin >> s; for (int i = 0 ; i < n; i++) { cout << string (m * 2 + 1 , '#' ) << endl; for (int j = 0 ; j < m; j++) { cout << '#' << (char )(vec[i][j] ^ 32 ); } cout << '#' << endl; } cout << string (m * 2 + 1 , '#' ) << endl; }
G.意欲现 思路 防AK。做法很像是贪心,但是这同时是一个dp优化技巧,叫做slope trick,可以用priority_queue将 $O(N^2)$ 的 dp 优化到 log 复杂度。
验题人乱搞搞过去的,然后被其他验题人指出来这个技巧后经验++了
这个题裸题在CF上2300
[Codeforces] Tutorial-Slope Trick
[博客园] 学习笔记 - Slope Trick
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void solve () { priority_queue<i64> que; int n, x; i64 ans = 0 ; cin >> n; while (n--) { cin >> x; que.push (x); if (x < que.top ()) ans += que.top () - x, que.pop (), que.push (x); } cout << ans << endl; }
H.六根归一 思路 根据 $x $ 和 $y$ 计算一下天数(注意余数加一),然后取模加一即可。
代码 1 2 3 4 5 6 7 8 void solve () { int x, y, a; cin >> x >> y >> a; int d = x / y + (x % y != 0 ); cout << (a - 1 + d) % 7 + 1 << endl; }
Fun Facts 1.本套新生赛出题人AK了黑神话悟空。
2.黑神话悟空的题面吸引来很多外校群友来验题。在此表达我对福建师范大学ACM队学长对我校新生赛一段时间以来的大力支持。他们的新生赛也好玩,有兴趣可以去打。
3.感谢所有集训队成员为新生赛做出的努力!