题解:P13677 [GCPC 2023] Loop Invariant
大致题意
给定一个字符串 ( 和 ) 组成,且括号配对。
求一个字符串
即:
如果不存在这样的字符串 no。
注:以上加粗字体提到,要在 别问我怎么知道的)。
思路
分割字符串
将字符串
例:字符串 ()(()())(()) 被分割为 ()、(()())、(()) 这
分情况讨论
无解情况
显然,一定存在某些字符串
如果不考虑
但是可能无法满足
观察发现:如果 no。
有解情况
反之,如果多个字符串并非都相等,就可以得到正确的
由于需要最小化
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int a[N], cnt, L, R;
string s;
int main(){
cin >> s;
for(int i=0; i<s.size(); i++){
if(L == R) // 此时可以分割了!
a[++cnt] = i, // 分割字符串端点
L = R = 0;
if(!i && cnt) --cnt; // 如果a[cnt]=0, 删除无用信息
// 左右括号匹配
L += (s[i] == '('),
R += (s[i] == ')');
}
// 最后一个也可以进行匹配
a[++cnt] = s.size();
bool flag = 0;
string head = s.substr(0, a[1]); // 分割后第一个小字符串
for(int i=2; i<=cnt; i++){
int x = a[i-1], y = a[i];
// s2 = s[x,y)
string s2 = s.substr(x, y-x); // 分割后其余小字符串
if(s2 != head){ // 并非全部相等
flag = 1;
break;
}
}
if(!flag){ // 全部相等, 无解
cout << "no";
return 0;
}
// 有解, 最小化i, 由于i=0时S'=S, 所以i=1
cout << s.substr(a[1]);
cout << s.substr(0, a[1]);
}