題解 P6439 [COCI2011-2012#6] ZAGRADE
阿新 • • 發佈:2021-06-26
演算法分析:記憶化搜尋
一道水題。
首先利用棧進行括號匹配,遇到左括號入棧,遇到右括號則把棧頂彈出並記錄。不多說,程式碼如下:
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 排序,在過程中就無需考慮字典序。於是就寫完了……
程式碼如下:
#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; }
歡迎交流討論,請點個贊哦~