Pinely Round 4 (Div. 1 + Div. 2)
题目链接:Pinely Round 4 (Div. 1 + Div. 2)
总结:被B卡了一年。
A. Maximize the Last Element
tag:模拟
Description:给定一个长度为奇数的数组,每次可以删除两个相邻的元素,直到剩下一个元素为止,求该元素的最大值。
Solution:模拟发现之后保留奇数位的值。
void solve(){ cin >> n; vector<int> a(n); for (int i = 0; i < n; i ++) cin >> a[i]; int ans = 0; for (int i = 0; i < n; i += 2) ans = max(ans, a[i]); cout << ans << endl; }
B. AND Reconstruction
tag:构造
Description:给定一个长为
Solution:我们令
Competing:一开始就想到了,但是思路不清晰,气。
void solve(){ cin >> n; vector<int> b(n), a(n); for (int i = 0; i < n - 1; i ++){ cin >> b[i]; } a[0] = b[0]; for (int i = 1; i < n - 1; i ++){ a[i] = b[i] | b[i - 1]; } a[n - 1] = b[n - 2]; for (int i = 0; i < n - 1; i ++){ if (b[i] != (a[i] & a[i + 1])){ cout << -1 << endl; return; } } for (int i = 0; i < n; i ++) cout << a[i] << " \n"[i + 1 == n]; }
C. Absolute Zero
tag:构造
Description:给定一个长度为
Solution:模拟几组样例发现,如果数组中所有元素的奇偶性必须相同,否则当一个数变为奇数,另一个数会变成偶数。(开始时这两个数奇偶性不同)。
- 我们只需要每次减去
,逐渐缩小上界即可。 - 可以使用
。逐渐缩小上界。
Competing:将
void solve(){ cin >> n; vector<int> a(n); for (int i = 0; i < n; i ++){ cin >> a[i]; } sort(a.begin(), a.end()); for (int i = 1; i < n; i ++){ if ((a[i] - a[i - 1]) & 1){ cout << -1 << endl; return; } } if (a[0] == a[n - 1]){ if (a[0] == 0){ cout << 0 << endl << endl; return; } cout << 1 << endl; cout << a[0] << endl; return; } vector<int> ans; while (a[0] != a[n - 1]){ int t = (a[n - 1] + a[0]) / 2; ans.eb(t); for (int i = 0; i < n; i ++){ a[i] = abs(a[i] - t); } sort(a.begin(), a.end()); } if (a[0] != 0) ans.eb(a[0]); cout << ans.size() << endl; for (int i = 0; i < ans.size(); i ++) cout << ans[i] << " \n"[i + 1 == ans.size()]; }
D. Prime XOR Coloring
tag:构造
四色定理:“将平面任意地细分为不相重叠的区域,每一个区域总可以用1234这四个数字之一来标记而不会使相邻的两个区域得到相同的数字。”这里所指的相邻区域是指有一整段边界是公共的。如果两个区域只相遇于一点或有限多点就不叫相邻的。
Description:有
Solution:考虑哪些点之间连边太难,考虑哪些点之间不连边。
- 根据四色定理知,当
时,一定需要四种颜色。 - 考虑所有质数,发现除了
都是奇数。 的二进制 , 的二进制 , 的二进制 。那么我们对 取余, 相同的数异或之后一定不是质数。 - 然后特判
。
void solve(){ cin >> n; if (n == 1){ cout << 1 << endl << 1 << endl; } else if (n == 2){ cout << 2 << endl; cout << 1 << " " << 2 << endl; } else if (n == 3){ cout << 2 << endl; cout << "1 2 2\n"; } else if (n == 4){ cout << 3 << endl; cout << "1 2 2 3\n"; } else if (n == 5){ cout << 3 << endl; cout << "1 2 2 3 3\n"; } else{ cout << 4 << endl; for (int i = 1; i <= n; i ++){ cout << (i % 4) + 1 << " \n"[i == n]; } } }
E. Coloring Game
tag:二分图 + 交互
Description:给定一个图,一共
选择三个颜色中选择两个颜色( )。 选择一个未染色的顶点进行染色。- 如果存在相邻顶点颜色相同
赢,否则 赢。 - 你需要选择玩家,并给出获胜策略。
Solution:显然
- 如果不是二分图,
获胜,每次输出 即可。 - 如果是二分图
获胜,先用 或者 将其中一种颜色染完,剩下的一种用 进行染色。因为 的个数加 的个数等于 ,因此必定有一种颜色会被染完。
void solve(){ cin >> n >> m; vector g(n, vector<int>()); vector st(n, -1); for (int i = 0; i < m; i ++){ int x, y; cin >> x >> y; x --, y --; g[x].eb(y); g[y].eb(x); } bool flag = true; vector<int> f1, f2; auto dfs = [&](auto self, int x, int fa, int c) -> void { st[x] = c; if (c == 1){ f1.eb(x); } else f2.eb(x); for (auto i : g[x]){ if (i == fa) continue; if (st[i] == -1){ self(self, i, x, !c); } else{ if (st[i] == c){ flag = false; } } } }; dfs(dfs, 0, -1, 1); if (flag){ cout << "Bob" << endl; int s1 = f1.size(), s2 = f2.size(); for (int i = 0; i < n; i ++){ int a, b; cin >> a >> b; if (a > b) swap(a, b); if (a == 1){ if (s1){ s1 --; cout << f1.back() + 1 << " " << a << endl; f1.pop_back(); } else{ s2 --; cout << f2.back() + 1 << " " << b << endl; f2.pop_back(); } } if (a == 2){ if (s2){ s2 --; cout << f2.back() + 1 << " " << a << endl; f2.pop_back(); } else{ s1 --; cout << f1.back() + 1 << " " << b << endl; f1.pop_back(); } } } } else{ cout << "Alice" << endl; for (int i = 1; i <= n; i ++){ int a, b; cout << "1 2" << endl; cin >> a >> b; } } }
F. Triangle Formation
tag:大氛围结论 + 小范围暴力
Description:给定
Solution:最长的不能组成三角形的序列:斐波拉契序列,因为
-
根据
,我们得到当 时,最大。因此序列长度超过 时,一定能够组成三角形。我们令区间长度为 ,那么当 时,一定有解。 -
考虑
,我们先将区间内的数排序。要想三边构成三角形,那么三条边要即可能接近。如给定 ,需要满足 ,假设 固定,那么 要尽可能大, 要尽快能小。因此三条边越接近越好。如果能从区间内找到两个无交集的三角形区间即符合条件。 -
考虑连续
个数组成两个三角形,假设现在有 个数 。第一个三角形为 ,那么第二个三角形为 。如果为 ,那么 不如 。同理如果为 ,那么 不如 。 -
假设现在有
六条边。其中 一定是长边, 一定是短边。- 如果
是长边,则 ,已讨论。 - 如果
是长边,则 ,三种情况。 - 如果
是长边,则 ,四种情况。
- 如果
void solve(){ int q; cin >> n >> q; vector<int> a(n + 1); for (int i = 1; i <= n; i ++) cin >> a[i]; while (q --){ int l, r; cin >> l >> r; if (r - l >= 60){ cout << "YES\n"; } else{ vector<int> b; for (int i = l; i <= r; i ++) b.eb(a[i]); sort(b.begin(), b.end()); int len = b.size(); int mi = -1, ma = -1; for (int i = 1; i + 1 < len; i ++){ if (b[i - 1] + b[i] > b[i + 1]){ if (mi == -1){ mi = i; continue; } ma = i; } } if (ma - mi >= 3){ cout << "YES\n"; } else{ bool ok = false; for (int i = 0; i + 5 < len; i ++){ vector<int> c(6); for (int j = 0; j < 6; j ++) c[j] = b[i + j]; if (c[0] + c[1] > c[3] && c[2] + c[4] > c[5]){ ok = true; break; } else if (c[0] + c[2] > c[3] && c[1] + c[4] > c[5]){ ok = true; break; } else if (c[1] + c[2] > c[3] && c[0] + c[4] > c[5]){ ok = true; break; } else if (c[0] + c[1] > c[4] && c[2] + c[3] > c[5]){ ok = true; break; } else if (c[0] + c[2] > c[4] && c[1] + c[3] > c[5]){ ok = true; break; } else if (c[0] + c[3] > c[4] && c[1] + c[2] > c[5]){ ok = true; break; } else if (c[1] + c[2] > c[4] && c[0] + c[3] > c[5]){ ok = true; break; } } if (ok) cout << "YES\n"; else cout << "NO\n"; } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!