P16308 [ICPC 2023 Jinan R] 很多很多头

思路

首先题目中提到两种括号的朝向可以任意,所以实际上同种类型的括号等价。
然后考虑合法(唯一)且仅存在 [A] 这种结构的括号序列(将其称为“简单括号序列”)长啥样。
发现一定是 [([(A)])] 状物或是 ([(A)]) 状物。
也就是两种括号必须交替出现。
若有一段出现了 [[A]],则可以被替换为 []A[],圆角括号也是一样,此时不是唯一构造。
然后考虑 AB 结构。
AB 的最外层是同一种,如 [A][B],则可以替换为 [A[]B],此时也不是唯一构造。
而如果存在三段及以上的“简单括号序列”,则根据抽屉原理一定存在两段的最外层相同,不是唯一构造。
所以得出结论:只能存在形如 [A] 的子结构,且最多有两个字结构,最外层还必须不同。
那么一个合法的序列就是 [A](B) 这样,转化一下变成 [A[(B(,然后 A 内部两种交替出现,B 内部两种交替出现,只有 AB 最内层会出现连续且类型相同的括号,所以只需统计有多少组连续相同的括号,判断是否少于两种即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<bits/stdc++.h>
#define fir first
#define sec second
#define int long long
#define pii pair<int,int>
#define fep(i,s,e) for(int i=s;i<e;i++)
#define pef(i,s,e) for(int i=s;i>e;i--)
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define per(i,s,e) for(int i=s;i>=e;i--)
namespace FastIO{
template<typename T>inline void read(T &x){
x=0;int f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);x*=f;
}
template<typename T,typename...Args>
inline void read(T &x,Args&...args){
read(x);
read(args...);
}
template<typename T>void print(T x){
if(x<0)x=-x,putchar('-');
if(x>9)print(x/10);
putchar((x%10)^48);
}
}
using namespace std;
using namespace FastIO;
int T,n,m;
string s;
signed main(){
read(T);
while(T--){
cin>>s;
fep(i,0,s.size()){
if(s[i]==')')s[i]='(';
if(s[i]==']')s[i]='[';
}
int cnt=0;
fep(i,1,s.size()){
if(s[i]==s[i-1])cnt++;
}
if(cnt<=2)puts("Yes");
else puts("No");
}
}