CF1303C Perfect Keyboard 题解
CF1303C Perfect Keyboard
我近期在狂刷 CF,好久没写题解了,今天来一发。
思路
通过观察,键盘上每一个字母最多只与两个字母相邻,所以当一个字母与两个以上的不同字母相邻时肯定是无解的,直接输出 NO。
接下来我们进行模拟。因为字母只有
接下来,我们将每个相邻字母数小于
为什么是小于 afghjfg。这组数据肯定是无解的,因为其中有环。环中字母的相邻字母数一定不小于
综上,本题大致思路已经完成。
代码
多组数据,记得清空。
预处理部分
for (int i = 1; i < n; i++)
{
if (!g[s[i]][s[i - 1]]) // 防止重复计算!
{
g[s[i]][s[i - 1]] = 1, g[s[i - 1]][s[i]] = 1; // g[u][v]: 是否存在 (u, v) 边
lk[s[i]]++, lk[s[i - 1]]++; // 双向边
if (lk[s[i]] > 2 || lk[s[i - 1]] > 2) // lk[i]: 字母 i 的相邻字母数
{
cout << "NO\n";
print = true;
break;
}
}
}
DFS 部分
void dfs(char u)
{
if (vis[u])
return ;
vis[u] = true; // 记录是否访问
ans += u; // ans: 构造结果
for (int v = 'a'; v <= 'z'; v++)
if (g[u][v] && v != u) // g[u][v]: 是否存在 (u, v) 边
dfs(v);
}
主函数核心部分
for (int i = 'a'; i <= 'z'; i++)
if (!vis[i] && lk[i] <= 1)
dfs(i);
for (int i = 'a'; i <= 'z'; i++)
{
if (!vis[i]) // 有字母没访问,一定存在环
{
cout << "NO\n";
print = true;
break;
}
}