我们考虑 什么样的 字符串 才不会出现 子序列存在 010、101的情况? 其中我们 可以认为 情况 1. 、2. 分别为 3. 、4. 情况的特殊情况,所以只要考虑 3.、4.情况, 对于3情况,我们预处理 前缀1的数量p1[i],在预处理后缀0的数量s0[i],这样我们我们循环遍历每一个i位置把i位置之前的1都变成0,把i以及其之后的位置的0都变成1,用预处理的 数据计算出花费的代价,在遍历的时候维护 代价的最小值 对与4.情况我们 同样进行预处理,同样的循环维护最小花费, 最终 就是两种的 花费的最小值就是答案 x-1-3 我们假设 叶子的节点的深度为0,那么其它叶子节点的深度都是确定的,,, 我们在考虑这种情况,玩家a不得不选择摘去一个深度为1的节点(假设摘去的节点为1),但是这个时候另一个玩家b是没法立刻就直接摘去x节点,因此此时x的度为2,表明x还不是叶子节点,所以没法摘,所以b玩家只能被迫摘去深度为1的🍃叶子节点(设为2),那么这个时候又出现了最后两个叶子节点分胜负的 情况了
题目传送门
A. Odd Selection
分析
代码
#include <bits/stdc++.h> using namespace std; void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); } void Fre() { freopen("A.txt", "r", stdin);} #define ios ios::sync_with_stdio(false) #define Pi acos(-1) #define pb push_back #define fi first #define se second #define ll long long #define ull unsigned long long #define db double #define Pir pair<int, int> #define PIR pair<Pir, Pir> #define INF 0x3f3f3f3f #define mod 998244353 const int mxn = 2e5 + 10; int ar[mxn]; int main() { /* fre(); */ int T; scanf("%d", &T); while(T --) { int n, x; scanf("%d %d", &n, &x); int odd = 0, eve = 0; for(int i = 1; i <= n; i ++) { scanf("%d", &ar[i]); if(ar[i] % 2) odd ++; else eve ++; } odd = min(odd, x); if(odd % 2 == 0) odd --; if(odd > 0 && odd + eve >= x) printf("Yesn"); else printf("Non"); } return 0; }
B. Subsequence Hate(前后缀和)
分析
代码
#include <bits/stdc++.h> using namespace std; void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); } void Fre() { freopen("A.txt", "r", stdin);} #define ios ios::sync_with_stdio(false) #define Pi acos(-1) #define pb push_back #define fi first #define se second #define ll long long #define ull unsigned long long #define db double #define Pir pair<int, int> #define PIR pair<Pir, Pir> #define INF 0x3f3f3f3f #define mod 998244353 const int mxn = 2e3 + 10; int p0[mxn], p1[mxn]; int s0[mxn], s1[mxn]; char ar[mxn]; int main() { /* fre(); */ int T; scanf("%d", &T); while(T --) { scanf("%s", ar + 1); int n = strlen(ar + 1); for(int i = 1; i <= n; i ++) { p0[i] = p0[i - 1]; p1[i] = p1[i - 1]; if(ar[i] == '0') p0[i] ++; else p1[i] ++; } s0[n + 1] = 0; s1[n + 1] = 0; for(int i = n; i >= 1; i --) { s0[i] = s0[i + 1]; s1[i] = s1[i + 1]; if(ar[i] == '0') s0[i] ++; else s1[i] ++; } int ans = INF; for(int i = 1; i <= n; i ++) { ans = min(ans, p1[i - 1] + s0[i]); ans = min(ans, p0[i - 1] + s1[i]); } ans = min(ans, p0[n]); printf("%dn", ans); } return 0; }
C. Game On Leaves(贪心+博弈?)
分析
去除上面特殊情况
以后,我们把x看做根节点,最后分出胜负的一定是,还剩下两个节点(x和 与x相连的一个节点)的时候,这个时候 该那个玩家出手,那个玩家获胜,
|
4-5-6
我们之后在假设,A先后 摘取了一个深度位2的节点(3节点),这个时候,聪明的B玩家肯定不会选择深度为1节点(如果选择了话 A直接就赢了),它可定会选择6节点;之后聪明的A也肯定不会选择深度为1的节点,它肯定会选择深度 > 1 的节点,这样防止对手直接获胜,就这样一直轮流操作下去…,总回出现剩余两最后两个节点的情况,,,
3-x-1
|
2
通过两个特殊的例子 大概的证明出了 最后一定会剩余2个节点
,而其它的节点都被玩家再去了,综上 当 (n – 1) % 2 为奇数的时候先手玩家获胜,否则后手获胜代码
#include <bits/stdc++.h> using namespace std; void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); } void Fre() { freopen("A.txt", "r", stdin);} #define ios ios::sync_with_stdio(false) #define Pi acos(-1) #define pb push_back #define fi first #define se second #define ll long long #define ull unsigned long long #define db double #define Pir pair<int, int> #define PIR pair<Pir, Pir> #define INF 0x3f3f3f3f #define mod (ll)(1e9 + 7) const int mxn = 2e5 + 10; int in[mxn]; int main() { /* fre(); */ int T; scanf("%d", &T); while(T --) { int n, x; scanf("%d %d", &n, &x); for(int i = 1, u, v; i < n; i ++) { scanf("%d %d", &u, &v); in[u] ++, in[v] ++; } if(in[x] <= 1 || (n - 1) % 2) printf("Ayushn"); else printf("Ashishn"); memset(in, 0, n * 4 + 4); } return 0; }
D. Guess The Maximums(交互题 + 二分)
分析
这个k个序列的元素值各不相同
(这题的突破口)si序列中的元素值为 A中元素的下标,先我们从这个k个序列中得出我们的长度为k的密码p序列,第i为密码为pi为 不在si序列中的序列A的下标以外的A中其它元素的最大值,
代码
#include <bits/stdc++.h> using namespace std; void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); } void Fre() { freopen("A.txt", "r", stdin);} #define ios ios::sync_with_stdio(false) #define Pi acos(-1) #define pb push_back #define fi first #define se second #define ll long long #define ull unsigned long long #define db double #define Pir pair<int, int> #define PIR pair<Pir, Pir> #define INF 0x3f3f3f3f #define mod 998244353 const int mxn = 2e3 + 10; vector<int> s[mxn]; int query(int n) { printf("? %d", n); for(int i = 1; i <= n; i ++) printf(" %d", i); printf("n"); fflush(stdout); //cout.flush(); int res; scanf("%d", &res); return res; } int n, k, mx; int find_max() { mx = query(n); int l = 1, r = n; while(l < r) { int mid = (l + r) >> 1; if(query(mid) != mx) l = mid + 1; else r = mid; } return l; } void get_ans() { vector<int> ans; int idx = find_max(); //最大值下标 for(int i = 1; i <= k; i ++) { auto it = find(s[i].begin(), s[i].end(), idx); if(it == s[i].end()) ans.pb(mx); else { map<int, int> mk; for(auto x : s[i]) mk[x] = 1; printf("? %lu", n - mk.size()); for(int j = 1; j <= n; j ++) { if(! mk[j]) printf(" %d", j); } printf("n"); fflush(stdout); int t_mx; scanf("%d", &t_mx); ans.pb(t_mx); } } printf("!"); for(auto x : ans) printf(" %d", x); printf("n"); fflush(stdout); string st; cin >> st; } int main() { /* fre(); */ int T; scanf("%d", &T); while(T --) { scanf("%d %d", &n, &k); for(int i = 1, c; i <= k; i ++) { scanf("%d", &c); for(int j = 1, t; j <= c; j ++) { scanf("%d", &t); s[i].pb(t); } } get_ans(); for(int i = 1; i <= k; i ++) s[i].clear(); } return 0; }
E. Tree Shuffling(dfs)
分析
代码
#include <bits/stdc++.h> using namespace std; void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); } void Fre() { freopen("A.txt", "r", stdin);} #define ios ios::sync_with_stdio(false) #define Pi acos(-1) #define pb push_back #define fi first #define se second #define ll long long #define ull unsigned long long #define db double #define Pir pair<int, int> #define PIR pair<Pir, Pir> #define INF 0x3f3f3f3f #define mod 998244353 const int mxn = 2e5 + 10; int a[mxn], b[mxn], c[mxn]; int ct1[mxn], ct0[mxn]; vector<int> e[mxn * 2]; ll res = 0; void dfs(int u, int p, int mon) { mon = min(mon, a[u]); for(auto v : e[u]) { if(v == p) continue; dfs(v, u, mon); ct0[u] += ct0[v]; //这里是维护 u的子树中,还剩余多少个 等待交换值的0节点 ct1[u] += ct1[v]; } if(b[u] != c[u]) { if(b[u] == 0) ct0[u] ++; else ct1[u] ++; } if(mon == a[u]) //在回溯的过程中 当前节点的费用==之前所有的祖先中最小的费用,那么我们就可确定,这个子树的所有需要变换数字的节点,所用的费用都应该是 a[u] { int c = min(ct0[u], ct1[u]); res += 2LL * c * mon; ct0[u] -= c; ct1[u] -= c; } } int main() { /* fre(); */ int n; scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%d %d %d", &a[i], &b[i], &c[i]); for(int i = 1, u, v; i < n; i ++) { scanf("%d %d", &u, &v); e[u].pb(v); e[v].pb(u); } dfs(1, 1, INF); if(ct0[1] || ct1[1]) printf("-1"); else printf("%lld", res); return 0; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算