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