AT_arc154_b 题解

发布时间 2023-07-26 13:58:03作者: So_noSlack

洛谷链接&Atcoder 链接

本篇题解为此题较简单做法较少码量,并且码风优良,请放心阅读。

题目简述

给定两个长度为 \(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!} \]