首页 > 代码库 > Codeforces 223A Bracket Sequence [栈]

Codeforces 223A Bracket Sequence [栈]

给一串由(,), [ ,]构成的字符串,求包含[最多的合法子串

很容易,先把整个字符串丢入栈里处理

栈的每一个元素存两个东西,字符,在字符串中的位置

处理方式为如果是()匹配则直接丢弃,如果是[]匹配则在这个点vis[i]++,然后求vis的前缀和

如果栈空,则说明整个串是合法的,直接输出串

否则,扫描栈中剩下的元素的位置,这几个位置把整个原串切割成几段,这几段肯定是合法的,求这几段中的含[最大的段,可以用前缀和求得,输出这段

游标,左右区间非常容易弄错。有一次手动输出了‘\0‘,导致看起来和答案一样,就是WA

#include <cstdio>
#include <climits>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
char str[111111];
int vis[111111];
int sumvis[111111];
struct STACK{
	char c;
	int pos;
}sta[111111];
int main(){
#ifndef ONLINE_JUDGE
	freopen("/home/rainto96/in.txt","r",stdin);
#endif
	cin>>str;
	int p=-1;
	int len =strlen(str);
	for(int i=0;i<len;i++){
		if(p!=-1){
			if(str[i]==')' && sta[p].c=='('){//直接丢弃
				p--;
				continue;
			}
			if(str[i]==']' && sta[p].c=='[') {//vis[i]++,便于快速求得段中含[的个数
				p--;
				vis[i]++;
				continue;
			}
			sta[++p]=(STACK){str[i],i};
		}else 	sta[++p]=(STACK){str[i],i};
	}
	sumvis[0]=vis[0];
	for(int i=1;i<len;i++)
		sumvis[i]=sumvis[i-1]+vis[i];
        if(p==-1){//如果栈里没有东西,则整个字符串合法,输出该串
                cout<<sumvis[len-1]<<endl;
                cout<<str<<endl;
                return 0;
	}
	int x=-1,y=-1,ans=0;//求栈中剩下元素使得原串分割的段中含[的最多的串
	int ansx=-1,ansy=-1;
	for(int i=0;i<=p;i++){
		y=sta[i].pos;
		int tmpans=sumvis[y-1]-sumvis[x]+(x==0?vis[x]:0);
		if(tmpans>ans){
			ans=tmpans;
			ansx=x+1;
			ansy=y-1;
		}
		x=y;
	}
        y=len;
        int tmpans=sumvis[y-1]-sumvis[x]+(x==0?vis[x]:0);
        if(tmpans>ans){
                ans=tmpans;
                ansx=x+1;
                ansy=y-1;
        }
	cout<<ans<<endl;
	//cout<<x<<endl;
	//cout<<y<<endl;
	if(ans>0){
                for(int i=ansx;i<=ansy;i++)
                        cout<<str[i];
        }
	cout<<endl;
}



Codeforces 223A Bracket Sequence [栈]