模拟
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k, a, b; cin >> n >> k >> a >> b; LL sum = (n - 1 + k - 1) * b; if (sum < (n - 1) * a) { cout << "1\n"; } else if (sum > (n - 1) * a) { cout << "2\n"; } else { cout << "0\n"; } return 0; }
鱼的位置和四个角落的曼哈顿距离取最大
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<string> a(n); int ans = 0; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (a[i][j] == '#') { ans = max({i + j, n - 1 - i + j, m - 1 - j + i, n - i + m - j - 2, ans}); } } } cout << ans << '\n'; return 0; }
考虑每一圈每块蛋糕至少要放多少块水果,因为是下取整,所以会有余数,要保持每圈之间每块蛋糕上水果差距不会太大,所以贪心的将余数水果优先分配给水果较少的蛋糕,如果还有剩余再分配给其他蛋糕
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k; vector<vector<int>> ans(k + 1, vector<int> (n + 1)); int pos = 1; for (int i = 1; i <= n; i++) { int x = i / k, y = i % k; for (int j = 1; j <= k; j++) { ans[j][i] += x; if (y > 0) { y--; ans[pos][i]++; pos++; if (pos == k + 1) { pos = 1; } } } } for (int i = 1; i <= k; i++) { for (int j = 1; j <= n; j++) { cout << ans[i][j] << " \n"[j == n]; } } return 0; }
可知通过反转操作,可以把小的点权都放在子树小的地方,而点权越大放在子树越大的地方即可
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<int> a(n + 1); vector<vector<int>> G(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 2; i <= n; i++) { int x; cin >> x; G[i].push_back(x); G[x].push_back(i); } vector<int> sz(n + 1); function<void(int, int)> dfs = [&](int u, int fa) { sz[u] = 1; for (auto v : G[u]) { if (v != fa) { dfs(v, u); sz[u] += sz[v]; } } }; dfs(1, 0); sort(sz.begin() + 1, sz.end()); sort(a.begin() + 1, a.end()); LL ans = 0; for (int i = 1; i <= n; i++) { ans = ans + 1LL * a[i] * sz[i]; } cout << ans << '\n'; return 0; }
将题目式子进行化简,发现满足条件当且仅当a[k]*a[k+len+1]=0,所以只需要提前处理出多少个符合条件的,然后每次单点修改讨论情况即可
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, len; cin >> n >> m >> len; vector<int> a(n + 1); int ans = 0; for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n - len - 1; i++) { if (1LL * a[i] * a[i + len + 1] == 0) { ans++; } } while (m--) { int pos, val; cin >> pos >> val; if (pos + len + 1 <= n and 1LL * a[pos] * a[pos + len + 1] == 0) { ans--; } if (pos - len - 1 >= 1 and 1LL * a[pos] * a[pos - len - 1] == 0) { ans--; } a[pos] = val; if (pos + len + 1 <= n and 1LL * a[pos] * a[pos + len + 1] == 0) { ans++; } if (pos - len - 1 >= 1 and 1LL * a[pos] * a[pos - len - 1] == 0) { ans++; } cout << ans << '\n'; } return 0; }
DP,一般思路就是从(1,1)一直转移到(1,n)(2,n)(3,n),但n的数值比较大,而如果很长时间没有经过机关,方案数是不变的,并且m较小,可以考虑直接看在机关处如何转移,发现只有中间那一行的机关在转移的时候和其他两行的机关有所不同,要特别判断在第几行,因此要提前按列数从小到大排序,每个机关至少要保留三列,所以要存储的最多是3*m列,然后就是一个基本的DP转移,当前点的方案数等于它前面所有下一步能走到它的方案数的和
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; const int mod = 998244353; int mp[4][3 * 500020], nxt[500020]; LL dp[4][3 * 500020]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<pair<int, int>> a(m); for (int i = 0; i < m; i++) { cin >> a[i].first >> a[i].second; } sort(a.begin(), a.end(), [&](pair<int, int> a, pair<int, int> b) { return a.second < b.second; }); for (int i = 0; i < m; i++) { int dist = a[i].second - a[i - 1].second; nxt[i] = nxt[i - 1] + min(2, dist); mp[a[i].first][nxt[i]] = 1; } dp[1][1] = 1; for (int i = 1; i <= 3 * 500010; i++) { for (int j = 1; j < 4; j++) { if (!(j == 2 and mp[j][i - 1])) { dp[j][i] = (dp[j][i] + dp[j][i - 1]) % mod; } if (i - 2 >= 0 and mp[j][i - 2]) { dp[j][i] = (dp[j][i] + dp[j][i - 2]) % mod; } if (j >= 2 and mp[j - 1][i - 1]) { dp[j][i] = (dp[j][i] + dp[j - 1][i - 1]) % mod; } if (j <= 2 and mp[j + 1][i - 1]) { dp[j][i] = (dp[j][i] + dp[j + 1][i - 1]) % mod; } } } cout << dp[1][3 * 500010] << '\n'; cout << dp[2][3 * 500010] << '\n'; cout << dp[3][3 * 500010] << '\n'; return 0; }
牛客小白月赛64(6/6)
最新推荐文章于 2024-07-15 21:33:54 发布