Educational Codeforces Round 104 (Rated for Div. 2)
A - Arena
题意
有一堆人打架,两个人打架战斗力强的赢,相等就谁也不赢。
问每次随机挑一对人打架,有多少人可能一直赢。
题解
随机就是说每个人只会跟最弱的打,如果当前人比最弱的强ans就+1。

#include <bits/stdc++.h> #define int long long #define Mid ((l + r) >> 1) #define lson (rt << 1) #define rson (rt << 1 | 1) using namespace std; int read(){ char c; int num, f = 1; while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0'; while(c = getchar(), isdigit(c)) num = num * 10 + c - '0'; return f * num; } int n, a[100009], cnt; void work() { n = read(); cnt = 0; for(int i = 1; i <= n; i++) a[i] = read(); sort(a + 1, a + 1 + n); for(int i = 1; i <= n; i++) { cnt += a[i] != a[1]; } printf("%lld\n", cnt); } signed main() { int Case = read(); while(Case--) work(); return 0; }
B - Cat Cycle
题意
有两只猫要睡觉,A猫第一天睡号点,第二天睡号点,第天回到号点睡觉,以此类推。
B猫从号点开始往后睡,但是B猫干不过A猫,如果B猫和A猫下一天会到同一个地方睡觉,则B猫会跳过那个位置,到下一天的位置睡。
现在问第天B猫睡在哪里。
题解
首先如果是偶数,他们就不会睡在同一个地方,直接对取模即可。
如果是奇数,说明有冲突,观察冲突是如何发生的。
AB猫一开始面对面,然后走格之后就会撞到,然后B猫多走一步。
然后AB猫变成背对背相邻了,把格铺开,其实问题又跟之前一样了,所以一共撞到次,就是多走这么多步,加上之后还是取模即可。

#include <bits/stdc++.h> #define int long long #define Mid ((l + r) >> 1) #define lson (rt << 1) #define rson (rt << 1 | 1) using namespace std; int read(){ char c; int num, f = 1; while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0'; while(c = getchar(), isdigit(c)) num = num * 10 + c - '0'; return f * num; } int n, k; void work() { n = read(); k = read(); if(n& 1) { k -= 1; k += k / (n / 2); k = k % n + 1; printf("%lld\n", k); } else { printf("%lld\n", (k - 1) % n + 1); } } signed main() { int Case = read(); while(Case--) work(); return 0; }
C - Minimum Ties
题意
一堆人打架,打赢了加3分,输了不加分,平局各加一分。
构造一种比赛状况使得最后总分一样的前提下平局最少。
题解
可以列一张表格, 平局为0。
首先如果是奇数个队伍的话就直接没有平局就行了,每个人赢场。
第一个人是的,第二个人是,表示没有这场比赛。
发现这东西是循环的。
然后考虑偶数,偶数的话不可能没有平局,就加入一场平局。
发现由于平局加的不是完整的3分,所以一旦一个人有了平局,就所有人都得有平局。
把第一个人改成就行了。
(考场上降智,脑筋急转弯题杀我。)

#include <bits/stdc++.h> #define Mid ((l + r) >> 1) #define lson (rt << 1) #define rson (rt << 1 | 1) using namespace std; int read(){ char c; int num, f = 1; while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0'; while(c = getchar(), isdigit(c)) num = num * 10 + c - '0'; return f * num; } void work() { int n = read(); if(n & 1) { for(int i = 1; i <= n; i++) for(int j = i + 1, cnt = 1; j <= n; j++, cnt++) printf("%d ", (cnt & 1) ? 1 : -1); } else { for(int i = 1; i <= n; i++) { for(int j = i + 1; j <= n; j++) { if(j - i == (n - 2) / 2 + 1) printf("0 "); else if(j - i <= (n - 2) / 2) printf("1 "); else printf("-1 "); } } } printf("\n"); } signed main() { int Case = read(); while(Case--) work(); return 0; }
D - Pythagorean Triples
题意
找到,使得,并且有的对数。
题解
还是考场降智我把直角三角形的条件看成是能组成三角形==。
看对题目这就是道傻逼题。
化简公式去掉,解出, 。
显然a必须是奇数。
据说有写法,但我写法是二分。
因为一旦一个可行,那么从到这个的所有奇数都可行,暴力二分就行了。

#include <bits/stdc++.h> #define int long long #define Mid ((l + r) >> 1) #define lson (rt << 1) #define rson (rt << 1 | 1) using namespace std; int read(){ char c; int num, f = 1; while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0'; while(c = getchar(), isdigit(c)) num = num * 10 + c - '0'; return f * num; } int n; void work() { n = read(); int l = 1, r = 1e5; while(l <= r) { int x = Mid * 2 + 1; if((x * x + 1) / 2 > n || x > n) r = Mid - 1; else l = Mid + 1; } printf("%lld\n", r); } signed main() { int Case = read(); while(Case--) work(); return 0; }
E - Cheap Dinner
题意
给定一张四层的分层图,每一层只会跟上一层有连边。
要求在每一层里面找出一个点,使得点是独立的并且点权和最小。
(独立指两两之间不能有连边)
题解
(最小点权独立集难道不是费用流吗)
由于只取一对,没必要用费用流。
考虑暴力dp。
每一个点的能不能取只跟上一层取了哪个点有关。
表示前i层,第i层的j点必须要取的最小代价。
从转移而来。
但是对于一个点又很多个k,但是由于注意到边在均摊给每个点之后,每个点均摊到的边其实很少,所以对于每个点的转移,一整段的东西是很多的,可以考虑数据结构维护。
用线段树或者ST表都可,只要维护区间最小值就行了。

#include <bits/stdc++.h> #define int long long #define Mid ((l + r) >> 1) #define lson (rt << 1) #define rson (rt << 1 | 1) using namespace std; int read(){ char c; int num, f = 1; while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0'; while(c = getchar(), isdigit(c)) num = num * 10 + c - '0'; return f * num; } int n[5], a[5][150009], f[5][150009], tree[150009 * 4]; vector<int> fa[5][150009]; void update(int rt) {tree[rt] = min(tree[lson], tree[rson]);} void build(int l, int r, int rt, int t) { if(l == r) {tree[rt] = f[t][l]; return ;} build(l, Mid, lson, t); build(Mid + 1, r, rson, t); update(rt); } int query(int l, int r, int L, int R, int rt) { if(L <= l && r <= R) return tree[rt]; int ans = 0x3f3f3f3f3f3f3f3f; if(L <= Mid) ans = min(ans, query(l, Mid, L, R, lson)); if(Mid < R) ans = min(ans, query(Mid + 1, r, L, R, rson)); return ans; } signed main() { memset(f, 0x3f, sizeof(f)); for(int i = 1; i <= 4; i++) n[i] = read(); for(int i = 1; i <= 4; i++) for(int j = 1; j <= n[i]; j++) a[i][j] = read(); for(int i = 2; i <= 4; i++) { int m = read(); for(int j = 1; j <= m; j++) { int x = read(), y = read(); fa[i][y].push_back(x); } } for(int i = 2; i <= 4; i++) { for(int j = 1; j <= n[i]; j++) { fa[i][j].push_back(n[i - 1] + 1); sort(fa[i][j].begin(), fa[i][j].end()); } } for(int i = 1; i <= n[1]; i++) f[1][i] = a[1][i]; build(1, n[1], 1, 1); for(int i = 2; i <= 4; i++) { for(int j = 1; j <= n[i]; j++) { int now = 0, minn = 0x3f3f3f3f3f3f3f3f; for(auto nxt : fa[i][j]) { if(nxt - 1 >= now + 1) minn = min(minn, query(1, n[i - 1], now + 1, nxt - 1, 1)); now = nxt; } f[i][j] = min(f[i][j], minn + a[i][j]); } build(1, n[i], 1, i); } int ans = 0x3f3f3f3f3f3f3f3f; for(int j = 1; j <= n[4]; j++) ans = min(ans, f[4][j]); printf("%lld\n", ans == 0x3f3f3f3f3f3f3f3f ? -1 : ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2019-02-16 [luogu]P2825 [HEOI2016/TJOI2016]游戏