- twiblr">Problem A - twiblr
- Almost GCD">Problem B - Almost GCD
- To 3">Problem C - To 3
- Wandering">Problem D - Wandering
- Akari">Problem E - Akari
- Valid payments">Problem F - Valid payments
Problem A - twiblr
直接输出
Problem B - Almost GCD
这里暴力枚举即可
int main() {ios_base::sync_with_stdio(false), cin.tie(0);int N;cin >> N;vector<int> A(N);for (int i = 0; i < N; ++i) cin >> A[i];int Max = 0, idx = -1;for (int i = 2; i <= 1000; ++i) {int cnt = 0;for (int j = 0; j < N; ++j)if (A[j] % i == 0) cnt++;if (Max < cnt) Max = cnt, idx = i;}cout << idx << '\n';return 0;}
Problem C - To 3
利用一个数能被 整除当且仅当其各位之和能被
整除。
- 如果本身能被
整除,则不需要删除。
- 如果被
除余
,则首先看是否能删去
个
,然后看是否能删去
个
。
- 如果被
除余
,则首先看是否能删去
个
,然后看是否能删去
个
。
C++ 代码
int main() {ios_base::sync_with_stdio(false), cin.tie(0);string s;cin >> s;int cnt[3] = {0};for (int i = 0; i < s.length(); ++i) cnt[(s[i] - '0') % 3]++;int cur = (cnt[1] + 2 * cnt[2]) % 3;int k = cnt[0] + cnt[1] + cnt[2];int res;if (!cur) res = 0;else if (cur == 1) {if (cnt[1])if (k == 1) res = -1;elseres = 1;else {if (k == 2) res = -1;elseres = 2;}} else {if (cnt[2]) {if (k == 1) res = -1;elseres = 1;} else {if (k == 2) res = -1;elseres = 2;}}cout << res << "\n";return 0;}
Python 代码
s = input()n = int(s)if n % 3 == 0:print(0)else:a = list(map(int, list(s)))c = [0] * 3for i in a:c[i % 3] += 1if c[n % 3] >= 1 and len(a) > 1:print(1)elif c[3 - n % 3] >= 2 and len(a) > 2:print(2)else:print(-1)
Problem D - Wandering
记录最远位置 ,当前位置
,前缀和
,以及前缀和的最大值
。
在每一轮中,首先更新前缀和,然后更新前缀和的最大值,本轮能达到的最大值显然是 ,用其更新
,再用
更新
。
时间复杂度 #card=math&code=%5Cmathcal%7BO%7D%28N%29)。
using ll = long long;int main() {ios_base::sync_with_stdio(false), cin.tie(0);int n;cin >> n;ll a, sum = 0, hi = 0, ans = 0, pos = 0;for (int i = 0; i < n; ++i) {cin >> a;sum += a;hi = max(hi, sum);ans = max(ans, pos + hi);pos += sum;}cout << ans << "\n";return 0;}
Problem E - Akari
将所有灯和墙都放到矩形中,然后逐行从左到右扫描一遍,再从右到左扫描一遍;逐列从上到下扫描一遍,再从下到上扫描一遍。最后统计亮着的格子即可。
时间复杂度 #card=math&code=%5Cmathcal%7BO%7D%28HW%29)。
#include <bits/stdc++.h>using namespace std;using ll = long long;int e[1510][1510];bool vis[1510][1510];int cnt = 0;struct node {int x, y;};int main() {ios_base::sync_with_stdio(false), cin.tie(0);int h, w, n, m;cin >> h >> w >> n >> m;vector<node> bulbs(n);for (int i = 0; i < n; ++i) {int x, y;cin >> x >> y, e[x][y] = 1; // bulbbulbs[i].x = x, bulbs[i].y = y;}for (int i = 0; i < m; ++i) {int x, y;cin >> x >> y, e[x][y] = 2; // block}for (int i = 0; i < n; ++i) {int x = bulbs[i].x, y = bulbs[i].y;if (vis[x][y] == false) {cnt++, vis[x][y] = true;}while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&x > 0 && x <= h && y > 0 && y <= w) {if (vis[x][y] == false) cnt++, vis[x][y] = true;x++;}x = bulbs[i].x, y = bulbs[i].y;while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&x > 0 && x <= h && y > 0 && y <= w) {if (vis[x][y] == false) cnt++, vis[x][y] = true;x--;}x = bulbs[i].x, y = bulbs[i].y;while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&x > 0 && x <= h && y > 0 && y <= w) {if (vis[x][y] == false) cnt++, vis[x][y] = true;y--;}x = bulbs[i].x, y = bulbs[i].y;while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&x > 0 && x <= h && y > 0 && y <= w) {if (vis[x][y] == false) cnt++, vis[x][y] = true;y++;}}cout << cnt << '\n';return 0;}
Problem F - Valid payments
dalao 题解,Orz…
#include <bits/stdc++.h>using namespace std;using ll = long long;const int N = 52;ll a[N], mx[N], xx[N], dp[N][2];int main() {ios_base::sync_with_stdio(false), cin.tie(0);int n;ll x, t;cin >> n >> x;for (int i = 1; i <= n; ++i) cin >> a[i];for (int i = 1; i < n; ++i) mx[i] = a[i + 1] / a[i];t = x;for (int i = n; i; --i) {xx[i] = t / a[i];t %= a[i];}dp[1][0] = 1;if (xx[1]) dp[1][1] = 1;for (int i = 1; i < n; ++i) {dp[i + 1][0] = dp[i][0];if (xx[i + 1]) dp[i + 1][1] = dp[i][0];dp[i + 1][1] += dp[i][1];if (xx[i + 1] + 1 != mx[i + 1]) dp[i + 1][0] += dp[i][1];}cout << dp[n][0] << '\n';return 0;}
这道题,我们实际上就是要求出满足
并且满足
的整数元组 的种数。
我们不妨从小到大进行选择。容易看到,我们其实只需要记录当前每一个可能达到的总数以及对应的方法数,而不需要记录对应的具体方案。因为总是
的倍数,所以在选择完
的系数kiki后,我们需要保证此时的总数能够被整除。同时,因为的限制,因此,对于每一个原有的状态,我们实际上只能有两种选择。
我们以作为初始状态开始递推。看起来,状态数会以指数规模增长,但实际上,任意时刻,我们最多同时保留两个状态,因此总时间复杂度为
#card=math&code=%5Cmathcal%7BO%7D%28N%29)。
using ll = long long;int main() {int n;ll x;cin >> n >> x;vector<ll> a(n);for (int i = 0; i < n; ++i) cin >> a[i];unordered_map<ll, ll> v;v[x] = 1;ll ans = 0;for (int i = 0; i < n; ++i) {unordered_map<ll, ll> nv;for (auto [c, f] : v) {if (i + 1 < n) {ll rem = c % a[i + 1];nv[c - rem] += f;if (rem > 0) nv[c + a[i + 1] - rem] += f;} else if (c % a[i] == 0)nv[0] += f;}v = move(nv);}cout << v[0];}
