T1:词典
题意:
给定 个长度为 的字符串 。
对于每个 询问是否存在 使得对于每个 , 都可以由 交换字符得到,且对于 都有 的字典序小于 。
数据范围:
, , 所有字符串均由小写字母构成
算法分析
做法1:
对于每个 , 如果存在方案的话必然可以让 字典序最小,而其他的 的 字典序最大。也就是让 的字符从小到大排序得到 ,让 的字符从大到小排序得到 。
直接模拟这个过程的时间复杂度为 ,期望得分 分。
但实际上可以拿 分。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { freopen("dict.in", "r", stdin); freopen("dict.out", "w", stdout); int n, m; cin >> n >> m; vector<string> w(n); rep(i, n) cin >> w[i]; vector<string> mn(n); rep(i, n) { mn[i] = w[i]; sort(mn[i].begin(), mn[i].end()); } vector<string> mx(n); rep(i, n) { mx[i] = w[i]; sort(mx[i].rbegin(), mx[i].rend()); } string ans; rep(i, n) { bool ok = true; rep(j, n) if (j != i) { if (mn[i] > mx[j]) { ok = false; break; } } ans += ok ? '1' : '0'; } cout << ans << '\n'; return 0; }
做法2:
实际上我们发现没有必要模拟上述过程,因为得到的 以及 一定是一段一段的,最多 段,使用桶存下每个字符的出现次数,之后一段一段比较即可在 的复杂度内解决。期望得到 分。
做法3:
不妨再深入一步,设 表示 中出现的最小字母, 表示 中出现的最大字母。
如果 ,那么显然 的字典序小于 ,只需要将 作为 的第一个字母, 作为 的第一个字母即可。
如果 ,那么显然 的字典序大于 。
剩下最后一种情况 ,想要 的字典序最小,需要将 放在最前面,此时越往后 的字母越大。想要 的字典序最大,需要将 放在最前面,此时越往后 的字母越小。因此此时必然有 的字典序大于 。
综上,如果 可能,当且仅当 。因此可以 完成这个过程,总的时间复杂度为 。
期望得分:100分。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { freopen("dict.in", "r", stdin); freopen("dict.out", "w", stdout); int n, m; cin >> n >> m; vector<int> f(n, 26), g(n, -1); rep(i, n) { string w; cin >> w; rep(j, m) { f[i] = min(f[i], w[j]-'a'); g[i] = max(g[i], w[j]-'a'); } } string ans; rep(i, n) { bool ok = true; rep(j, n) if (j != i) { if (f[i] >= g[j]) { ok = false; break; } } ans += ok ? '1' : '0'; } cout << ans << '\n'; return 0; }
T2:三值逻辑
题意:
有三种变量: 以及一种运算 。且满足运算法则:,,。
已知现在有 个变量 ,有 条赋值语句,每条语句为以下三种之一:
- ,其中 是 三者之一
在执行 条语句之前,会先对变量赋初始值。求所有使得执行 条语句之后,每个变量初始值与最终值相等的初始赋值中, 变量的最小值。数据保证有解。
数据范围:
,。多组数据, 表示数据组数。
算法分析
做法1:
直接 枚举每种可能的初始值,之后再使用 的时间判断,可以获得 分。
做法2:( 可能取值 )
此时可以发现,一个变量需要赋值为 当且仅当 条语句结束之后变量的值为 ,因此我们可以记录每个变量的状态:未赋值,赋值为 ,赋值为 ,赋值为 。这个可以 得到。
期望得分: 分。
做法3:( 可能取值为 )
此时与上一种情况略有区别,一个变量需要赋初值为 除了最终值为 之外,还多了某个变量最终值为 ,而 的最终值为这个变量。例如 :
此时由于 的值为 ,导致 的值也必须为 。
这就启发我们要记录 的最终值是哪里来的。而这是好记录的,初始时每个 的来源都是本身,当执行 时,记录 的来源为 的来源即可,而对于 ,则直接标记来源为 ,如果某个值最终来源为 ,则说明其最终值为 。
最终可以使用并查集(如果 的来源是 ,说明 的最终值等于 的初始值,进一步 的初始值等于 的初始值,因此将 和 放入一个集合),如果集合内有一个变量初始值为 ,则集合内所有变量的初始值必须为 。
时间复杂度为
期望得分: 分。
做法4:
最终我们可以沿用上述思路,记录每个变量的来源(注意 时 可能等于 )以及是否被取反(也就是逻辑非运算)。
之后我们可以使用并查集维护命题,具体来说对于每个 建立两个点, 表示命题 , 表命题 。显然正常情况 与 是不会在同一个集合中的,而一旦它们在同一个集合中,就只能说明 ,即 。
之后对于每个 考虑 的来源
- 为 ,说明 的最终值为 ,将 与 并入同一集合
- 为 或者 ,由于题目保证有解,而 的最终值为 或者 ,说明不可能为 ,此时我们不需要做任何处理。
- 为 ,说明 的值与 的值一致,将 与 并入同一集合,将 与 并入同一集合。
- 为 ,说明 的值与 的值相反,将 与 并入同一集合,将 与 并入同一集合。
最终 与 在同一集合的变量 的个数就是所求答案。
时间复杂度为
期望得分: 分
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) using namespace std; const int N = 2e5+5; const int U = N-1; const int T = N-2; int val[N], p[N]; int root(int x) { if (p[x] == x) return x; return p[x] = root(p[x]); } void merge(int x, int y) { p[root(x)] = root(y); } bool same(int x, int y) { return root(x) == root(y); } void solve() { int n, m; cin >> n >> m; rep(i, n) val[i] = i; rep(mi, m) { char v; int i, j; cin >> v >> i; if (v == '+' or v == '-') { cin >> j; int x = val[j]; val[i] = v == '-' ? -x : x; } else { val[i] = v == 'U' ? U : T; } } rep(i, n*2) p[i] = i; rep(i, n) { if (abs(val[i]) == U) merge(i, i+n); else if (abs(val[i]) == T) continue; else if (val[i] > 0) { merge(val[i], i); merge(val[i]+n, i+n); } else if (val[i] < 0) { merge(-val[i], i+n); merge(-val[i]+n, i); } } int ans = 0; rep(i, n) if (same(i, i+n)) ans++; cout << ans << '\n'; } int main() { freopen("tribool.in", "r", stdin); freopen("tribool.out", "w", stdout); int c, t; cin >> c >> t; while (t--) solve(); return 0; }
T3:双序列拓展
题意:
称 是 的扩展,当且仅当存在 使得 是将 中的 替换为 个 得到的。
给出长度为 的序列 以及长度为 的序列 ,问是否存在 的拓展 ,以及 的拓展 ,满足 和 的长度均为 ,且对于任意的 都有 。
有 组数据,每组数据都是在原序列的基础上修改若干个元素得到的。
数据范围:
- 修改的数量之和不超过
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现