AT_arc154_b 题解
本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。
题目简述
给定两个长度为 \(n\) 的字符串 \(S,T\),定义一次操作可取出 \(S\) 的首位,插到 \(S\) 的任意位置。
求最少的操作次数使 \(S\) 变成 \(T\),无解输出 -1
。
思路
首先很容易想到如果 \(S\) 和 \(T\) 的某个字母的个数不同,那么 \(S\) 不可能变为 \(T\)。因为不可能凭空变出一个字母。通过两个桶数组即可记录 \(S,T\) 的每个字母个数:
int cnt_s[30], cnt_t[30];
for(int i = 0; i < n; i ++)
cnt_s[s[i] - 'a'] ++, cnt_t[t[i] - 'a'] ++;
接着验证 \(S\) 和 \(T\) 的各个字母数量是否一致,一旦不一致立刻输出 -1
即可:
for(int i = 0; i < 26; i ++)
if(cnt_s[i] != cnt_t[i]) {
cout << "-1\n";
return 0;
}
特判 -1
的情况后就很简单了,仅需遍历 \(T\) 即可,在过程中如果 \(S\) 的当前位与 \(T\) 相同,则表示不必进行操作,把之前记录的 \(ans\) 自减即可。
经过以上分析,很容易即可得出完整代码了:
#include<iostream>
using namespace std;
int n, cnt_s[30], cnt_t[30], ans = 0; // 必要数组不解释
string s, t; // 模式串和匹配串
int main() {
cin >> n >> s >> t;
ans = n - 1; // 因为下标从 0 开始,所以 ans 需初始化为 n - 1
for(int i = 0; i < n; i ++) cnt_s[s[i] - 'a'] ++, cnt_t[t[i] - 'a'] ++; // 统计字母个数
for(int i = 0; i < 26; i ++)
if(cnt_s[i] != cnt_t[i]) {
cout << "-1\n"; // 字母个数不相同直接输出
return 0;
}
for(int i = n - 1; i >= 0; i --)
if(s[ans] == t[i]) ans --; // 满足条件不必操作,ans --
cout << ans + 1 << endl; // 还是下标问题答案需 +1,建议写下标从 1 开始的
return 0;
}
\[\text{The End!}
\]
本文来自博客园,作者:So_noSlack,转载请注明原文链接:https://www.cnblogs.com/So-noSlack/p/17582282.html