比赛时候没有ac可惜
题目翻译
尼尔·瓦茨博士是西格蒙德公司的一名技术专家,他开发了一台原型机器,能够修改绝症患者的记忆。他用字符串来表示这些记忆。
在这种情况下,我们使用两个长度相同的字符串,分别记为 (S) 和 (T)。这两个字符串都仅由小写英文字母组成。字符串 (S) 代表患者的原始记忆,而字符串 (T) 代表目标记忆。最终目标是对字符串 (S) 执行若干操作,使其与字符串 (T) 相同。
记忆修改机器使用一个名为 rshift k
的基本函数来执行操作,其中 (1 \leq k \leq 25)。这个函数会将一个字母变为字母表中在它之后第 (k) 个字母。在这种情况下,字母 (z) 之后的字母被认为是 (a)。
然而,由于记忆修改可能会改变时间线的走向,瓦茨博士在每次操作中只能对字符串 (S) 的一个后缀应用 rshift k
操作。对于每次操作,可以任意选择 (k) 的值以及后缀的长度。
例如,如果对从字母 (w) 开始的后缀应用 rshift 3
操作,字符串 uvwxyz
将会变为 uvzabc
。
由于过多的记忆操作可能会导致意外后果,瓦茨博士需要将执行的操作次数减到最少。因此,他需要你帮忙确定将字符串 (S) 转换为字符串 (T) 所需的最少操作次数。
输入:
第一行包含一个整数 (n)((1 \leq n \leq 2 \times 10^5)),表示字符串的长度。
第二行包含一个由 (n) 个小写英文字母组成的字符串 (S)。
第三行包含一个由 (n) 个小写英文字母组成的字符串 (T)。
输出:
输出一个整数,表示将字符串 (S) 转换为字符串 (T) 所需的最少操作次数。
方法思路
问题分析:每个操作对后缀的字符进行统一移动,我们需要找到最少的操作次数使得 S 转换为 T。关键在于如何高效地覆盖多个字符的调整需求。
关键洞察:每次操作对后缀的影响是累加的,后面的字符会被多次操作。因此,我们可以通过维护一个当前累积移动量(pyl),从左到右遍历字符串,每当当前累积移动量与目标移动量不匹配时,进行一次操作。
算法选择:贪心算法。通过维护当前累积移动量,逐个检查每个字符的位置需求,当需求变化时进行操作,并更新累积移动量。
算法流程
计算移动差值:对于每个字符位置 i,计算 S[i] 到 T[i] 的移动差值 diff,取模 26 确保非负。
遍历比较:维护一个变量 current 表示当前累积的移动量。遍历每个字符位置,如果当前累积移动量与目标移动量不匹配,则计数一次操作,并更新 current 为目标移动量。
时间复杂度
计算移动差值:O(n),每个字符处理一次。
遍历比较:O(n),每个字符处理一次。
总时间复杂度:O(n),其中 n 是字符串长度。
#include <bits/stdc++.h>
using namespace std;
int n;
string a, b;
int res;
int main()
{
cin >> n >> a >> b;
int pyl = 0;
for (int i = 0; i < n; i ++ )
{
int a_val = a[i] - 'a', b_val = b[i] - 'a';
int diff = (a_val - b_val + 26) % 26;
if (pyl != diff)
{
res ++ ;
pyl = diff;
}
}
cout << res << endl;
return 0;
}