CF 题目集锦 PART 1 #138 div 1 A
Posted 阿蒋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 题目集锦 PART 1 #138 div 1 A相关的知识,希望对你有一定的参考价值。
【#138 div 1 A. Bracket Sequence】
【原题】
A. Bracket Sequence time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output
A bracket sequence is a string, containing only characters "(", ")", "[" and "]".
A correct bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters "1" and "+" between the original characters of the sequence. For example, bracket sequences "()[]", "([])" are correct (the resulting expressions are: "(1)+[1]", "([1+1]+1)"), and "](" and "[" are not. The empty string is a correct bracket sequence by definition.
A substring s[l... r] (1 ≤ l ≤ r ≤ |s|) of string s = s1s2... s|s| (where |s| is the length of string s) is the string slsl + 1... sr. The empty string is a substring of any string by definition.
You are given a bracket sequence, not necessarily correct. Find its substring which is a correct bracket sequence and contains as many opening square brackets «[» as possible.
InputThe first and the only line contains the bracket sequence as a string, consisting only of characters "(", ")", "[" and "]". It is guaranteed that the string is non-empty and its length doesn't exceed 105 characters.
OutputIn the first line print a single integer — the number of brackets «[» in the required bracket sequence. In the second line print the optimal sequence. If there are more than one optimal solutions print any of them.
Sample test(s) input([])output
1 ([])input
(((output
0
【题意】给定长度为N的小、中括号序列,求一个符合括号匹配的子串,使得中括号最多。
【分析】开始想的有点麻烦。感觉是O(N)的扫过去,遇到“)”和“]”注意判无解(如果无解前面全部舍弃掉),然后中括号匹配是这样的——判断这个]和与之匹配的[的“前缀左小括号个数”(显然“(“是会被“)”消掉的)。但是叉点重重。比如[][],第二组中括号要和第一组发生关系,因此还要用一个类似并查集的东西维护。写起来超级麻烦。
【题解】网上看的思路真是超级清晰。我们用O(N)的方法算出每个点最多能拓展到哪里。
倒着扫,用P[i]表示第i个点向右最多匹配几个字符(包括自己)。
比如当前是i,那么我们知道i+1~i+P[i+1]已经是i+1最大合法状态了。
设next=i+P[i+1]+1,那么判断一下s[i]和s[next]是否匹配。
如果匹配,就能使i~next全部匹配。这是还要判断一下:next+1后面能否继续匹配呢?
于是P[i]=next-i+1+P[next+1],即把next+1的匹配项也加进去。(就想[][]的形态)
注意,不需要加next+1+P[next+1]的P,因为这已经算在P[next+1]上了- -。
【代码】
#include<cstdio>
#include<cstring>
#define N 100005
using namespace std;
char s[N];int num[N],P[N],ans,i,x,y,L,next;
int main()
scanf("%s",s+1);L=strlen(s+1);
for (i=1;i<=L;i++)
num[i]+=num[i-1]+(s[i]=='[');
P[L]=0;x=1;y=0;
for (i=L-1;i;i--)
if (s[i]==')'||s[i]==']') continue;
next=i+1+P[i+1];
if (s[i]=='('&&s[next]==')'||s[i]=='['&&s[next]==']')
P[i]=next-i+1+P[next+1];
for (i=1;i<=L;i++)
if (num[i+P[i]-1]-num[i-1]>ans)
ans=num[i+P[i]-1]-num[i-1],x=i,y=i+P[i]-1;
printf("%d\\n",ans);
for (i=x;i<=y;i++) printf("%c",s[i]);
return 0;
以上是关于CF 题目集锦 PART 1 #138 div 1 A的主要内容,如果未能解决你的问题,请参考以下文章
CF1103C Johnny Solving (Codeforces Round #534 (Div. 1)) 思维+构造