[Ceoi2016|BZOJ4936] Match
生活随笔
收集整理的這篇文章主要介紹了
[Ceoi2016|BZOJ4936] Match
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
哈希+分治+stack
題目:
給你一個由小寫字母組成的字符串s,要你構造一個字典序最小的(認為左括號的字典序比右括號小)合法的括號?
序列與這個字符串匹配,字符串和括號序列匹配定義為:首先長度必須相等,其次對于一對匹配的左括號和右括號?
i,j,必須有s[i]==s[j]?
無解輸出-1
?
很坑:括號配對原來是最近的左括號右括號算一對...我以為隨便怎么配只要左括號右括號數量相等且能左右分離就好了...
首先是判斷無解情況:開一個stack,碰到和top相同的彈掉,如果最后stack不空就必然無解
?
然后是分治即可
顯然對于Solve(l,r)的l元素的'('我們要找離其最遠的')',當然這是要可行的前提下
難點是如何判斷可行情況:在記錄stack的情況下維護hash,出棧減掉,入棧加上,當Hash(l-1)==Hash(r)的時候(l,r)是可行區間
至于分治寫起來就不難了
std好像是map,但是昨天寫了一晚上的hash,就直接打hash了
而且用map在這里反而比hash要復雜!
代碼:
1 #include<bits/stdc++.h> 2 #define ull unsigned long long 3 using namespace std; 4 inline int read(){ 5 int ans=0,f=1;char chr=getchar(); 6 while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();} 7 while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();} 8 return ans*f; 9 }const int M=1e5+5,B=131; 10 ull f[M],p[M],now; 11 char s[M],st[M],ans[M]; 12 int top,n; 13 void Solve(int l,int r){ 14 if(l>=r) return; 15 for(int p=r;;p--) 16 if(s[l]==s[p]&&f[l-1]==f[p]&&(p==r||f[p]==f[r])){ 17 ans[l]='(',ans[p]=')'; 18 Solve(l+1,p-1); 19 p<r?Solve(p+1,r):Solve(2,1); 20 break; 21 } 22 } 23 int main(){ 24 freopen("match.in","r",stdin); 25 freopen("match.out","w",stdout); 26 scanf("%s",s+1); 27 n=strlen(s+1); 28 p[0]=1; 29 for(int i=1;i<=n;i++) p[i]=p[i-1]*B; 30 for(int i=1;i<=n;i++){ 31 if(s[i]==st[top]) now-=p[top--]*(s[i]-'a'+1); 32 else now+=p[++top]*(s[i]-'a'+1),st[top]=s[i]; 33 f[i]=now; 34 }if(top) return puts("-1"),0; 35 Solve(1,n); 36 printf("%s",ans+1); 37 return 0; 38 }?
轉載于:https://www.cnblogs.com/zhenglw/p/11178008.html
總結
以上是生活随笔為你收集整理的[Ceoi2016|BZOJ4936] Match的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring 源码分析01
- 下一篇: mybatis分页插件PageHelpe