[01ACM NEEuropean][URAL1183]Brackets sequence

Brackets sequence

Time Limit: 1.0 second

Memory Limit: 16 MB

Let us define a regular brackets sequence in the following way:

  1. Empty sequence is a regular sequence.
  2. If S is a regular sequence, then (S) and [S] are both regular sequences.
  3. If A and B are regular sequences, then AB is a regular sequence.

For example, all of the following sequences of characters are regular brackets sequences:

(), [], (()), ([]), ()[], ()[()]

And all of the following character sequences are not:

(, [, ), )(, ([)], ([(]

Some sequence of characters ‘(‘, ‘)’, ‘[', and ']‘ is given. You are to find the shortest possible regular brackets sequence, that contains the given character sequence as a subsequence. Here, a string a1a2…an is called a subsequence of the string b1b2…bm, if there exist such indices 1 ≤ i1 < i2 < … < in ≤ m, that aj=bij for all 1 ≤ j ≤ n.

Input

The input file contains at most 100 brackets (characters ‘(‘, ‘)’, ‘[' and ']‘) that are situated on a single line without any other characters among them.

Output

Write to the output file a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.

Sample

Input Ouput
([(] ()[()]

Problem Author: Andrew Stankevich
Problem Source: 2001-2002 ACM Northeastern European Regional Programming Contest

Solution

终于过了这题……WA了两次。第一次是判断括号匹配的栈写错了,WA#9;第二次是没有考虑输入文件是空串的情况,WA#13并持续一周 -_-|||

而且这次也写垃圾了,长达80多行。好像原来的ural的内存限制是1000K?这样说我开一个100*100的string数组真是件奢侈的事情呢……

#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
using namespace std;
ifstream fin("bracket.in");
ofstream fout("bracket.out");
string S;
inline bool isregular(int i,int j)	//判断原串中的子串S[i...j]是否规则
{
	if(j<i)	return true;
	else if(j==i)	return false;
	char stack[100];	int p=0;
	for(int k=i;k<=j;k++)
	{
		if(p==0)
		{
			if(S[k]=='('||S[k]=='[')	stack[p++]=S[k];
			else return false;
		}
		else{
			if(( stack[p-1]=='('&&S[k]==')' )||( stack[p-1]=='['&&S[k]==']' ))	p--;
			else if(S[k]==')'||S[k]==']')	return false;
			else	stack[p++]=S[k];
		}
	}
	return (p==0);
}
string s[100][100];	//[i][j]:按照最少原则添加括号规则化S[i...j]后得到的串
string memo(int i, int j)	//记忆化搜索
{
	if(s[i][j]!="")	return s[i][j];
	if(isregular(i,j))	//若S[i...j]本身就已经是规则的
	{
		s[i][j].assign(S,i,j-i+1);
		return s[i][j];
	}
	if(i==j)	//若当前串仅由一个字符组成
	{
		if(S[i]=='('||S[i]==')')	s[i][j]="()";
		else if(S[i]=='['||S[i]==']')	s[i][j]="[]";
		else assert(0);
		return s[i][j];
	}
	string ans,tmp,tmp2;
	unsigned size=UINT_MAX;
	if(( S[i]=='('&&S[j]==')' )||( S[i]=='['&&S[j]==']' ))	//若S[i...j]首尾配对,则只需使S[i+1...j-1]规则就得到一个解
	{
		ans=S[i]+memo(i+1,j-1)+S[j];
		size=ans.size();
	}
	else if(( S[i]=='('&&S[j]!=')' )||( S[i]=='['&&S[j]!=']' ))	//S[i...j]首尾不配对,与以上类似
	{
		ans=S[i]+memo(i+1,j);
		if(S[i]=='(')	ans=ans+')';
		else if(S[i]=='[')	ans=ans+']';
		else assert(0);
		size=ans.size();
	}
	else if(( S[i]!='('&&S[j]==')' )||( S[i]!='['&&S[j]==']' ))
	{
		ans=memo(i,j-1)+S[j];
		if(S[j]==')')	ans='('+ans;
		else if(S[j]==']')	ans='['+ans;
		else assert(0);
		size=ans.size();
	}
	for(int k=i;k<j;k++)	//规则化S[i...k]和S[k+1...j]后合并得到的串
		if(size>memo(i,k).size()+memo(k+1,j).size())
		{
			ans=memo(i,k)+memo(k+1,j);
			size=memo(i,k).size()+memo(k+1,j).size();
		}
	return (s[i][j]=ans);
}
int main()
{
	fin >> S;
	if(S.size()==0)
	{
		fout << endl;
		return 0;
	}
	fout << memo(0,S.size()-1) << endl;
	return 0;
}

可能你对下面的文章也感兴趣:

    分享到:
  • http://blog.sina.com.cn/u/1249004412 依可依

    看不懂.,..

标签云