31 条题解
-
7账号已注销 LV 7 @ 2017-10-08 08:43:50
抛砖引玉,分享两种做法。
第一种,栈,因为我很菜鸡所以开了不少大数组。
具体思路:遇到左括号就进栈q(保存位置,f保存相对应的右括号)。遇到右括号判断栈顶元素是否与之对应,对应则出栈,将括号内范围标1(f1数组);不对应则栈清空,这一块都不行了。最后循环找出最长的括号串输出。
菜鸡我一开始是保存的起始点,后来发现有并列情况啊不好处理。
代码如下:#include<cstdio> #include<cstring> int q[5000005],top; bool f1[5000005]; char c[5000005],f[5000005]; int main() { int i,j,maxn=0,s=0,x=0,mx,l; scanf("%s",c); l=strlen(c); for (i=0;i<l;i++) { if (c[i]=='(') {q[++top]=i; f[top]=')';} if (c[i]=='[') {q[++top]=i; f[top]=']';} if (c[i]=='{') {q[++top]=i; f[top]='}';} if ((c[i]==')'||c[i]==']'||c[i]=='}')&&top) if (f[top]!=c[i]) top=0; else { for (j=q[top];j<=i;j++) f1[j]=1; top--; } } for (i=0;i<l;i++) if (f1[i]) s++; else { if (s>maxn) {maxn=s; mx=x;} s=0; x=i+1; } if (s>maxn) {maxn=s; mx=x;} for (i=mx;i<mx+maxn;i++) printf("%c",c[i]); return 0; }
解法2:dp。
呐,就是公式比较麻烦啦直接进代码。#include<cstdio> #include<cstring> int dp[5000005],maxn; char c[5000005]; int main() { int i,l; scanf("%s",c); l=strlen(c); for (i=1;i<l;i++) { if ((c[i]==')'&&c[i-1-dp[i-1]]=='(') ||(c[i]==']'&&c[i-1-dp[i-1]]=='[') ||(c[i]=='}'&&c[i-1-dp[i-1]]=='{')) dp[i]=dp[i-1]+2/*处理嵌套*/+dp[i-2-dp[i-1]]/*处理并列*/; if (dp[i]>dp[maxn]) maxn=i; } for (i=maxn-dp[maxn]+1;i<=maxn;i++) printf("%c",c[i]); printf("\n"); return 0; }
-
12009-07-17 09:53:48@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms其实无需这么复杂.
设f[i]为第i个字符为末尾的和谐字串的最大长度,s[i]为原串.
伪代码如下:
if s[i] 为右括号 then
if s 为配套的左括号 then f[i]=f+2
else if s[i-f-1] 为配套的左括号 then
f[i]=f+2;
(若第i位之前有和谐字串,若这个和谐字串前为配套的左括号,那么从第i位开始的和谐字串的长度可以达到前面和谐字串的长度+2)最后只需把连续的字串连起来就可以了.复杂度为O(n).
我的程序写的不好,但都可以做到只有30行.(pascal)
-
02017-07-14 10:33:11@
本来我的思路是很清晰的,后来写着写着发现自己题目理解错了一半2333,顺带为啥我没有碰到套括号的优先级这中东西。。
#include<iostream> #include<stack> #include<cstring> using namespace std; char stringData[5000000]; bool Data[5000000]; typedef struct slash{ char Slash; int pos; }slash; stack<slash>check; int main(void){ cin>>stringData; int index=0,ansBegin=0,ansEnd=0,length=0; while(stringData[index]!='\0'){ if(stringData[index]=='('||stringData[index]=='['||stringData[index]=='{'){ auto p=new slash; p->Slash=stringData[index]; p->pos=index; check.push(*p); } else{ if(check.size()==0){ } else if((check.top().Slash=='('&&stringData[index]==')')||(check.top().Slash=='['&&stringData[index]==']')|| (check.top().Slash=='{'&&stringData[index]=='}')){ { ansBegin=check.top().pos; ansEnd=index; for(int i=ansBegin;i<=ansEnd;i++){ Data[i]=1; } } check.pop(); } else{ //clear the stack int Size=check.size(); for(int i=0;i<Size;i++){ check.pop(); } } } index++; } int begin=0,end=0; for(int i=0;i<strlen(stringData);i++){ if(i==0&&Data[i]==1){ begin=0; } else if(Data[i]==1&&Data[i-1]==0){ begin=i; } else if(Data[i]==1&&Data[i+1]==0){ end=i; if(length<end-begin){ ansEnd=end; ansBegin=begin; length=ansEnd-ansBegin; } } } for(int i=ansBegin;i<=ansEnd;i++){ cout<<stringData[i]; } }
-
02016-10-25 20:59:36@
拿测试数据和前人发过的AC代码我亲自测试,输出结果和output明明一模一样,tmd测评就是WA!!!!!!!!
-
02016-09-13 11:30:01@
#include<stdio.h>
#include<string.h>
#include<stack>
#include<algorithm>
using namespace std;
stack<char>a;
stack<int>b;
char bra[5000005];
int main()
{
scanf("%s", bra);
int len=strlen(bra);
a.push(')');
b.push(0);
int i;
for(i=0;i<=len;i++)
{
if(a.top()-bra[i]==-1||a.top()-bra[i]==-2)
{
a.pop();
b.pop();
}
else
{
a.push(bra[i]);
b.push(i+1);
}
}
a.push('(');
b.push(i+1);
int max=0;
int start;
int end;
while(b.top()!=0)
{
int tmp=b.top();
b.pop();
int tmp_=b.top();
if(tmp-tmp_>=max)
{
start=tmp;
end=tmp_;
max=start-end-1;
}
}
for(i=end;i<=start-2;i++)
{
printf("%c",bra[i]);
}
return 0;
} -
02014-03-16 14:52:07@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms├ 测试数据 04:答案正确... 56ms
Accepted 有效得分:100 有效耗时:56ms
-
02009-10-31 14:40:30@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 56ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:56ms合并区间通用解法
while (f[i]>0) and (ak[a[f[i]]]ak[a[i]]-1) do f[i]:=f[f[i]];
if (f[i]>0) and (ak[a[f[i]]]=ak[a[i]]-1) then dec(f[i])
else f[i]:=-1;
while f[f[i]]>=0 do f[i]:=f[f[i]]; -
02009-10-28 11:42:36@
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 9ms
直接用栈。。。 如果配对就弹栈
再记下每一个压入栈的位置。 -
02009-10-27 16:38:08@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 41ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:41ms万分感谢 sdvsda 的帮助
-
02009-10-06 18:59:10@
模拟栈即可!~~~~~
同表达式计算过程一样。
-
02009-08-12 11:08:55@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:运行超时...
├ 测试数据 03:运行超时...
├ 测试数据 04:内存溢出...
---|---|---|---|---|---|---|---|-
Unaccepted 有效得分:1 有效耗时:0msMG~~
-
02009-08-10 13:23:12@
ri。。。。题意有问题,其实同样长度有优先级的……太恶心了……
-
02009-07-31 11:54:37@
开始把调试用的表交上去了,浪费一次提交。
程序很短,只有26行。
另外,非常感激sdvsdv神牛的详细题解! -
02009-08-16 16:25:30@
就按照大牛们的方法做
-
02009-07-11 22:43:11@
ws题 强烈抗议
-
02009-07-10 21:10:41@
怎么有点像‘迎春舞会之交谊舞’(1062)
-
02009-07-10 21:10:11@
提醒各位:“套括号”优先于“并括号”!
-
02009-07-11 11:53:51@
= = 囧
-
02009-07-10 08:37:45@
强烈抗议把这题的输出更改成:
最长和谐字串长度题目根本没讲清楚,如果有多个长度一样的该怎么输出。
就算LX有人说并列优先于套起来,那么下面几个例子怎么办?
1.{} 和 [] 输出哪个?
2.{[]}[] 和 []{[]} 输出哪个? -
02009-07-09 22:00:37@
好吧 我承认 单纯栈是不行的 除非特殊处理~~~
BS zgx 为什么会有多解。。。。1s的程序错了!!! 恭喜你 没有注意特殊情况
给出几个优化:
bs:=0;
for i:=1 to l-1 do
begin
j:=ord(s)-ord(s[i]); 〈==看这两行
if (j=1) or (j=2) then 〈==这个判断是利用ASCII码的
begin
bs:=bs+1; b[bs].x:=i; b[bs].y:=i+1;
end;
end;
next:=true;
while (next) do
begin
next:=false;
for i:=1 to bs do
if (b[i].x>1) and (b[i].y