Educational Codeforces Round 91 (Rated for Div. 2) ABCD
A. Three Indices
如果存在一组解$a_i<a_j>a_k$,我们考察$a_{j-1},a_j,a_{j+1}$是否构成一组解,若不满足,则再考察$a_{j-1}$或$a_{j+1}$,直到边界$a_i,a_k$。于是如果序列有解,必然存在一组解$a_{j-1}<a_j>a_{j+1}$,$O(n)$扫描一遍就可以了。
B. Universal Solution
分别计算每一个$C_i$对win(1)+win(2)+⋯win(n)的贡献值,发现最大贡献值对应赢下S串中出现最多次数的操作,$O(n)$扫描即可。
C. Create The Teams
容易通过反证发现,优先把$a_i$高的编入队中可得到最优解。
D. Berserk And Fireball
队列中的战士互不相同且无法改变顺序,则可以$O(n)$在$a$中依次标记出所有$b$中元素,若无法标记则输出$-1$。然后在$a$中就分割出了需要删除的小区间,分类讨论如何删除最优。若区间长度$num<k$,需要考虑使用Berserk能否全部删除;若区间长度$num>=k$,首先一定能通过Berserk将区间删除至$k$倍$num$,然后判断Berserk是否比Fireball操作更优,若Berserk更优,是否能使用Berserk全部删除。注意细节模拟即可。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int p[1010]; int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &p[i]); bool flag = false; for (int i = 2; i < n; i++) { if (p[i] > p[i - 1] && p[i] > p[i + 1]) { flag = true; puts("YES"); printf("%d %d %d\n", i - 1, i, i + 1); break; } } if (!flag) puts("NO"); } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char s[200010]; int cnt[300]; int main() { int T; scanf("%d", &T); while (T--) { cnt['R'] = 0; cnt['P'] = 0; cnt['S'] = 0; scanf("%s", s + 1); int len = strlen(s + 1); for (int i = 1; i <= len; i++) cnt[s[i]]++; int ans = cnt['R']; ans = max(ans, max(cnt['P'], cnt['S'])); if (ans == cnt['R']) { for (int i = 1; i <= len; i++) putchar('P'); } else { if (ans == cnt['P']) for (int i = 1; i <= len; i++) putchar('S'); else for (int i = 1; i <= len; i++) putchar('R'); } putchar('\n'); } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100010]; int main() { int T; scanf("%d", &T); while (T--) { int n, x; scanf("%d%d", &n, &x); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a + 1, a + n + 1); int cnt = 1, ans = 0; for (int i = n; i >= 1; i--) { if (cnt * a[i] >= x) { ans++; cnt = 1; } else cnt++; } printf("%d\n", ans); } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int a[200010], b[200010]; int ne[200010]; int main() { int n, m; scanf("%d%d", &n, &m); ll x, y, k; scanf("%lld%lld%lld", &x, &k, &y); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= m; i++) scanf("%d", &b[i]); int pos = 1, la = 0; for (int i = 1; i <= n; i++) { if (a[i] == b[pos]) { ne[la] = i; la = i; pos++; } } if (pos <= m) { puts("-1"); return 0; } int end = la, num, cnt; ll ans = 0; num = ne[0] - 1; if (num < k) { for (int i = 1; i < ne[0]; i++) { if (a[i] > a[ne[0]]) { puts("-1"); return 0; } } ans += (ll)num * y; } else { if (k * y < x) { bool flag = true; for (int i = 1; i < ne[0]; i++) { if (a[i] > a[ne[0]]) { flag = false; break; } } if (flag) ans += (ll)num * y; else ans += x + (ll)(num - k) * y; } else { ans += (ll)num / k * x; num %= k; ans += (ll)num * y; } } for (int i = ne[0]; i != end; i = ne[i]) { num = ne[i] - i - 1; if (num < k) { for (int j = i + 1; j < ne[i]; j++) { if (a[j] > a[i] && a[j] > a[ne[i]]) { puts("-1"); return 0; } } ans += (ll)num * y; } else { if (k * y < x) { bool flag = true; for (int j = i + 1; j < ne[i]; j++) { if (a[j] > a[i] && a[j] > a[ne[i]]) { flag = false; break; } } if (flag) ans += (ll)num * y; else ans += x + (ll)(num - k) * y; } else { ans += (ll)num / k * x; num %= k; ans += (ll)num * y; } } } num = n - end; if (num < k) { for (int i = end + 1; i <= n; i++) { if (a[end] < a[i]) { puts("-1"); return 0; } } ans += (ll)num * y; } else { if (k * y < x) { bool flag = true; for (int i = end + 1; i <= n; i++) { if (a[end] < a[i]) { flag = false; break; } } if (flag) ans += (ll)num * y; else ans += x + (ll)(num - k) * y; } else { ans += (ll)num / k * x; num %= k; ans += (ll)num * y; } } printf("%lld\n", ans); return 0; }