题解 CF1766B Notepad#
大家好,我是 CQ-C2024 蒟蒻 CJH。
题意
给定一个字符串,有以下两个操作:
-
在字符串的结尾添加任何一个字母。
-
复制一个已经输入的字符串的连续子串,并将这个子串粘贴到字符串的结尾。
请用小于 $n$ 个操作,完成这个字符串。
分析
因为要小于 $n$ 次操作完成这个字符串,所以不可能每一次都添加单独一个字符或复制单独一个字符。
所以字符串必须要存在两个不重叠且长度大于 $1$ 的相同子串,这样才能保证可以少用一次操作就可以添加两个字符。
只需要用 map<string,int> 来记录每两个字符构成的子串第一次出现的位置,如果有出现过还需要判断这两个子串是否重叠。
注意事项
如果你的 map 定义在全局中,一定要清空。多测不清空,爆零两行泪。
代码
//the code is from chenjh
#include<bits/stdc++.h>
using namespace std;
string s;
map<string,int> m;
void solve(){
m.clear();//定义在全局中一定要清空!
int n;scanf("%d",&n);
cin>>s;
string tmp;
for(int i=0;i<n-1;i++){
tmp=(char)s[i];
tmp+=(char)s[i+1];//取出字符串的第 i 和 i+1 个字符,构成一个长度为 2 的子串。
if(m.find(tmp)==m.end()) m[tmp]=i;//如果不存在这个字串则标记当前位置。
else{
if(m[tmp]!=i-1){//如果不重叠。
puts("YES");
return;
}
}
}
puts("NO");
}
int main(){
int t;scanf("%d",&t);
while(t--) solve();
return 0;
}

浙公网安备 33010602011771号