题解 P6439 [COCI2011-2012#6] ZAGRADE
算法分析:记忆化搜索
一道水题。
建议难度:黄。
首先利用栈进行括号匹配,遇到左括号入栈,遇到右括号则把栈顶弹出并记录。不多说,代码如下:
inline void cot() {
stack<int> s;
F(i,1,n) {
if(c[i]=='(')s.push(i);
if(c[i]==')')b[++cnt]= {s.top(),i},s.pop();
}
}
然后就是搜索,由于括号数量较少,可以用状压记录使用情况。对于每一种状态,暴力统计消去的括号的位置,然后再暴力将剩余的字符加到一个字符串中。用 string 储存,最终可以直接 sort 排序,在过程中就无需考虑字典序。于是就写完了……
code:
#include<bits/stdc++.h>
#define reg register
#define F(i,a,b) for(reg int i=a;i<=b;++i)
using namespace std;
const int N=1e4+10,M=250;
int n,cnt,now;
bool vis[M],meet[N];
char c[M];
struct P {
int l,r;
} b[N];
string s[N];
inline void cot() {//括号匹配
stack<int> s;
F(i,1,n) {
if(c[i]=='(')s.push(i);
if(c[i]==')')b[++cnt]= {s.top(),i},s.pop();
}
}
inline void inp(int sta) {//暴力组合字符
++now;
F(i,1,cnt) {
int l=b[i].l,r=b[i].r;
if(sta&(1<<i-1))vis[l]=vis[r]=1;
}
F(i,1,n){
if(!vis[i])s[now]+=c[i];
vis[i]=0;
}
}
void dfs(int sta) {
if(meet[sta])return;
meet[sta]=1;//记忆化
if(sta)inp(sta);//记录当前状态下的字符串
F(i,1,cnt) {//搜索
if(sta&(1<<i-1))continue;
dfs(sta|(1<<i-1));
}
}
int main() {
getline(cin,s[0]);
n=s[0].size();
F(i,0,n-1)if(s[0][i]!=' ')c[i+1]=s[0][i];
cot();
dfs(0);
sort(s+1,s+now+1);//排序
now=unique(s+1,s+now+1)-s-1;//去重
F(i,1,now)cout<<s[i]<<endl;
return 0;
}
欢迎交流讨论,请点个赞哦~
本文来自博客园,作者:Maplisky,转载请注明原文链接:https://www.cnblogs.com/lbh2021/p/14932733.html