2023河南萌新联赛第(五)场:郑州轻工业大学
文章目录
- 2023河南萌新联赛第(五)场:郑州轻工业大学
- D [01分数规划](https://ac.nowcoder.com/acm/contest/62977/D)
- B [亚托莉 -我挚爱的时光-](https://ac.nowcoder.com/acm/contest/62977/B)
- J [树上DP](https://ac.nowcoder.com/acm/contest/62977/J)
- G [Kruskal](https://ac.nowcoder.com/acm/contest/62977/G)
- I [双指针](https://ac.nowcoder.com/acm/contest/62977/I)
- A [买爱心气球](https://ac.nowcoder.com/acm/contest/62977/A)
- E [换根DP](https://ac.nowcoder.com/acm/contest/62977/E)
- L [异或与](https://ac.nowcoder.com/acm/contest/62977/L)
- M [扫描线](https://ac.nowcoder.com/acm/contest/62977/M)
D 01分数规划
给你一个字符串 s s s,由 0 0 0, 1 1 1, ? ? ?组成, ? ? ?可以替换为 1 1 1或 0 0 0,求可能的最长的 1 1 1串或 0 0 0串的长度。
可以用 d p dp dp直接把 ? ? ?的可能状态进行转移
也可以直接把所有 ? ? ?看成 1 1 1跑一遍,再看成 0 0 0跑一边取最大。
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int n;
cin >> n;
string s;
cin >> s;
vector<vector<int>> dp(2, vector<int>(2));
int ans = 0;
for (int i = 0; i < n; i++) {
if (s[i] == '?') {
dp[i & 1][0] = dp[(i + 1) & 1][0] + 1;
dp[i & 1][1] = dp[(i + 1) & 1][1] + 1;
} else if (s[i] == '1') {
dp[i & 1][1] = dp[(i + 1) & 1][1] + 1;
dp[i & 1][0] = 0;
} else {
dp[i & 1][0] = dp[(i + 1) & 1][0] + 1;
dp[i & 1][1] = 0;
}
ans = max(dp[i & 1][0], ans);
ans = max(dp[i & 1][1], ans);
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
B 亚托莉 -我挚爱的时光-
模拟安装,卸载(不清除个人数据,清除个人数据),以及删库跑路
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
set<string> soft, data;
int n;
cin >> n;
while (n--) {
string s;
cin >> s;
if (s == "1") {
cin >> s;
if (soft.count(s)) {
cout << "yes" << endl;
} else {
cout << "no" << endl;
}
} else if (s == "2") {
cin >> s;
if (data.count(s)) {
cout << "yes" << endl;
} else {
cout << "no" << endl;
}
} else if (s == "pacman") {
cin >> s;
if (s == "-R") {
cin >> s;
soft.erase(s);
} else {
cin >> s;
soft.erase(s);
data.erase(s);
}
} else {
cin >> s;
if (s == "pacman") {
cin >> s >> s;
soft.insert(s);
data.insert(s);
} else {
cout << "wuwuwu" << endl;
exit(0);
}
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
return 0;
}
J 树上DP
节点的深度越大在子树中出现的次数越多
计算每个点的深度,再将其和 a i a_i ai排序求乘积和就是最大
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int n;
cin >> n;
vector<vector<int>> g(n);
vector<int> a(n), dep(n), val(n, 1);
for (int i = 1; i < n; i++) {
int x, y;
cin >> x >> y;
x--, y--;
g[x].push_back(y);
g[y].push_back(x);
}
for (int i = 0; i < n; i++) {
cin >> a[i];
}
auto dfs = [&](auto self, int x, int fa) -> void {
for (auto u : g[x]) {
if (u == fa) continue;
dep[u] = dep[x] + 1;
self(self, u, x);
}
};
dep[0] = 1;
dfs(dfs, 0, -1);
sort(a.begin(), a.end());
sort(dep.begin(), dep.end());
int ans = 0;
for (int i = 0; i < n; i++) {
ans += a[i] * dep[i];
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
G Kruskal
可以发现,除了 n n n每位都是 1 1 1的时候答案为 1 1 1之外,其他答案都是 0 0 0。
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int n;
cin >> n;
while (n) {
if (n & 1) {
n >>= 1;
} else {
cout << 0 << endl;
return;
}
}
cout << 1 << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
I 双指针
等式两边转化一下,变成 a i b i = b j a j \frac{a_i}{b_i} = \frac{b_j}{a_j} biai=ajbj
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int n;
cin >> n;
vector<int> a(n), b(n);
for (auto& x : a) cin >> x;
for (auto& x : b) cin >> x;
map<double, int> mp;
int ans = 0;
for (int i = 0; i < n; i++) {
ans += mp[b[i] * 1.0 / a[i]];
mp[a[i] * 1.0 / b[i]]++;
// cout << i << ' ' << ans << endl;
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
A 买爱心气球
找规律可以发现 m m o d 3 = = n m \mod 3==n mmod3==n时后手才能赢
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int m, n;
cin >> m >> n;
if (n == m % 3) {
cout << "Bob" << endl;
} else {
cout << "Alice" << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
E 换根DP
其实就是考虑哪条 1 1 1边将树分的最不平均,取重的一边都是 1 1 1,轻的一边都是 2 2 2
这样我们只需从所有叶子开始向内即可,对边为1的特殊处理一下
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int n;
cin >> n;
vector<vector<pii>> g(n);
vector<int> du(n), sz(n, 1);
for (int i = 1; i < n; i++) {
int x, y, w;
cin >> x >> y >> w;
x--, y--;
g[x].push_back({ y, w });
g[y].push_back({ x, w });
du[x]++;
du[y]++;
}
queue<int> q;
for (int i = 0; i < n; i++) {
if (g[i].size() == 1) {
q.push(i);
}
}
int ans = n - 1;
while (q.size()) {
auto x = q.front();
// cout << x << ' ' << sz[x] << endl;
q.pop();
for (auto [u, v] : g[x]) {
if (v == 1) {
ans = min(ans, sz[x]);
}
du[u]--;
if (du[u] == 1) {
sz[u] += sz[x];
q.push(u);
} else {
sz[u] += sz[x];
}
}
}
cout << n - 2 + ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
return 0;
}
L 异或与
可以发现,两个数要满足条件就需要从低位开始看,只有碰到都是 1 1 1的时候下一位才是不一样的,其他都是 0 0 0
#include <bits/stdc++.h>
typedef long long ll;
#define int ll
#define endl '\n'
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define debug(x) cout << #x << " = " << x << endl
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int mod = 998244353;
const int N = 2e5 + 10;
void solve() {
int n;
cin >> n;
map<int, int> mp;
auto calc = [&] (int x) {
int res = 0;
for (int i = 0; i < 61; i++) {
if (x >> i & 1) {
res |= (1ll << i);
if (!(x >> (i + 1) & 1)) {
res |= (1ll << (i + 1));
}
i++;
}
}
return res;
};
for (int i = 1, x; i <= n; i++) {
cin >> x;
if (mp[x]) {
cout << mp[x] << ' ' << i << endl;
return;
}
mp[calc(x)] = i;
}
cout << -1 << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
return 0;
}
M 扫描线
旋转卡壳