Codeforces Round 868 (Div. 2) ABCDE
F 待补 TAT
A. A-characteristic
题意
给定
思路
设
枚举即可,时间复杂度
代码
点击查看代码
#include <iostream>
#define f(x, y, z) for (int x = (y); x <= (z); ++x)
using namespace std;
int tt, n, k;
void solve() {
cin >> n >> k;
f(a, 1, n) {
int b = n - a;
if (a * (a - 1) / 2 + b * (b - 1) / 2 == k) {
cout << "YES\n";
f(i, 1, a) cout << "1 ";
f(i, 1, b) cout << "-1 ";
cout << '\n';
return;
}
}
cout << "NO\n";
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> tt;
while (tt--) solve();
return 0;
}
B. Sort with Step
题意
给定一个
你还可以在一开始交换任意两个
你的任务是判断:
- 能否在一开始不用任意交换的情况下,使得
变为升序; - 如果不能,能否在一开始用一次任意交换的情况下,使得
变为升序。
如果满足条件 1 输出
思路
我们发现,如果一开始不用任意交换,设一个数
任意交换的作用就是使两个本来不能移动到自己位置的数变得能够移动到自己位置。这样的操作具有 对称性。于是,只要 恰好有两个数 不满足存在
代码
点击查看代码
#include <iostream>
#define f(x, y, z) for (int x = (y); x <= (z); ++x)
using namespace std;
int tt, n, k;
void solve() {
cin >> n >> k;
int x, cnt = 0;
f(i, 1, n) {
cin >> x;
if ((x - i) % k) ++cnt;
}
if (!cnt) cout << "0\n";
else if (cnt == 2) cout << "1\n";
else cout << "-1\n";
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> tt;
while (tt--) solve();
return 0;
}
C. Strongly Composite
题意
定义 强合数 为:合因子个数大于等于素因子个数的数(大于
现在给定序列
; 中的所有数都是强合数; 尽可能地大。
输出最大化的
思路
显然,我们需要将
注意到题目中说
可以发现,如果用不同的质因子,至少需要
于是我们贪心地使用相同的质因子尽量凑完全平方数,如果某种质因子最后只剩下
时间复杂度 std::map
需要再带一个
代码
点击查看代码
#include <iostream>
#include <map>
#define f(x, y, z) for (int x = (y); x <= (z); ++x)
using namespace std;
typedef pair<int, int> pii;
int constexpr N = 1e7 + 10;
int tt, n;
map<int, int> mp;
void get_prime_factor(int x) {
for (int i = 2; i <= x / i; ++i)
while (!(x % i)) ++mp[i], x /= i;
if (x ^ 1) ++mp[x];
return;
}
void solve() {
cin >> n;
int x;
mp.clear();
f(i, 1, n) {
cin >> x;
get_prime_factor(x);
}
int ans = 0, tmp = 0;
for (pii i: mp) {
ans += (i.second >> 1);
tmp += (i.second & 1);
}
ans += tmp / 3;
cout << ans << '\n';
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> tt;
while (tt--) solve();
return 0;
}
*D. Unique Palindromes(字符串构造)
题意
令
给定整数
构造一个由小写拉丁字母组成的长度为
思路
引理:如果在原字符串
证明:考虑反证法,如果增加超过
因此,无解的充分条件即为
首先考虑单独一个条件
这是由于
接下来考虑如何满足所有
代码
点击查看代码
#include <iostream>
#define f(x, y, z) for (int x = (y); x <= (z); ++x)
using namespace std;
int constexpr N = 2e5 + 10;
char constexpr abc[3] = {'a', 'b', 'c'};
int tt, n, k, x[21], c[21];
char s[N];
void solve() {
cin >> n >> k;
f(i, 1, k) cin >> x[i];
f(i, 1, k) cin >> c[i];
char ch = 'd';
int t = 0;
f(i, 1, k) {
if (x[i] - x[i - 1] < c[i] - c[i - 1]) return cout << "NO\n", void();
int l = x[i - 1] + 1, r = x[i - 1] + c[i] - c[i - 1];
if (i == 1) r -= 3;
f(j, l, r) s[j] = ch;
++ch;
f(j, r + 1, x[i]) s[j] = abc[t], (++t) %= 3;
}
cout << "YES\n";
f(i, 1, n) cout << s[i];
cout << '\n';
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> tt;
while (tt--) solve();
return 0;
}
*E. Removing Graph(SG 函数)
题意
Alice 和 Bob 正在一张简单无向图上玩一个游戏。图中有
Alice 和 Bob 轮流行动,Alice 先手。每次行动中,玩家可以选择
给定
思路
学习笔记:Nim 游戏基础 - f2021ljh - 博客园
每个节点的度数为
显然,每一个环是独立的,那么根据 SG 定理,整个游戏的
对于一个环,第一次行动时显然会破环成链。于是可以先求链的
设大小为
把大小为
对于一条长度为
注意 两种情况的
然而这样只是
令
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 4 | 4 | 4 | 4 | |
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 4 | 4 | 0 | 0 |
可以发现:
( )(证明见下); ( ),因为总可以令 (由于 ),而两个相同的数的异或值为 ;
在 1, 2 成立的情况下,3 成立是显而易见的(注意不要把
下面证明
显然
有 。下面考虑 的情况。
假设命题在上都成立。
:令 , 为 上的任意一个数,则有
:对于所有 满足 ,有 于是
。根据数学归纳法,命题成立。
代码
点击查看代码
#include <vector>
#include <iostream>
#define f(x, y, z) for (int x = (y); x <= (z); ++x)
using namespace std;
int constexpr N = 2e5 + 10;
int n, l, r, ans;
vector<int> edge[N];
int col[N], tot, siz[N];
void dfs(int u) {
col[u] = tot;
++siz[tot];
for (int v: edge[u])
if (!col[v]) dfs(v);
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> l >> r;
int u, v;
f(i, 1, n) {
cin >> u >> v;
edge[u].push_back(v), edge[v].push_back(u);
}
f(i, 1, n) if (!col[i]) ++tot, dfs(i);
f(i, 1, tot) if (siz[i] <= l + r - 1) ans ^= (siz[i] / l);
if (ans) cout << "Alice\n";
else cout << "Bob\n";
return 0;
}
F. Random Walk
题意
一棵
你的目标是移动到点
- 均匀随机地选择一个
的相邻节点 ( 是 的相邻节点当且仅当树中存在一条边 ); - 移动到
,并且令 累加 。
在到达
对于每个节点
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现