【题目来源】
https://www.acwing.com/problem/content/4893/
【题目描述】
给定一个字符串,其中的每个字符要么是 M,要么是 O。
你可以通过以下操作将该字符串变为 MOO:
改变字符串中的第一个或最后一个字符(M 变为 O,O 变为 M)。
删除字符串中的第一个或最后一个字符。
请你计算,为了将给定字符串变成 MOO,所需要的最少操作次数。
【输入格式】
第一行包含整数 Q,表示共有 Q 组测试数据。
每组数据占一行,包含一个字符串,其中的每个字符要么是 M,要么是 O。
【输出格式】
每组数据输出一行结果,一个整数,表示所需要的最少操作次数。如果无解,则输出 -1。
【数据范围】
1≤Q≤100,
每个字符串的长度范围 [1,100]。
【输入样例】
3
MOMMOM
MMO
MOO
【输出样例】
4
-1
0
【样例解释】
第一个字符串 MOMMOM 变为 MOO 最少需要 4 步操作,一种可行方案为:
将最后一个字符变为 O。
删除第一个字符。
删除第一个字符。
删除第一个字符。
第二个字符串无法变为 MOO。
第三个字符串已经是 MOO,无需任何操作。
【算法分析】
★ s.substr(pos,len):返回字符串 s 中从 pos 开始的 len 个字符的子串
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin>>s;
for(int i=0; i<s.size()-2; i++) {
string t=s.substr(i,3);
cout<<t<<endl;
}
return 0;
}
/*
in:
abcdefg
out:
abc
bcd
cde
def
efg
*/
★ 样例分析
首先字符串至少要有 3 位,没有直接输出 -1。
我们三位三位模拟取最小值,只要中间是 O,都可以变成 MOO。也就是说,由M和O组成的三位字符串虽然有“OOO、OOM、OMO、OMM、MOO、MOM、MMO、MMM”等8种组合,但通过题目给出的两种操作,能变为MOO的初始字符串只能是含有“MOO、MOM、OOO、OOM”等四种子串的字符串。
操作次数如下:
MOO:0 次。
MOM:1 次。
OOO:1 次。
OOM:2 次。
最终取最小值加上总长度 -3 即可。因为最终只能保留 3 位。如果 t 仍是初始值,那么输出 -1。
【算法代码】
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int main() {
int T;
cin>>T;
while(T--) {
string s;
cin>>s;
if(s.size()<3) {
cout<<"-1"<<endl;
continue;
}
int t=inf;
for(int i=0; i<s.size()-2; i++) {
string sub=s.substr(i,3);
if(sub=="MOO") t=min(t,0);
else if(sub=="MOM") t=min(t,1);
else if(sub=="OOO") t=min(t,1);
else if(sub=="OOM") t=min(t,2);
}
if(t==inf) cout<<"-1"<<endl;
else cout<<t+s.size()-3<<endl;
}
return 0;
}
/*
in:
3
MOMMOM
MMO
MOO
out:
4
-1
0
*/