括号画家
Candela是一名漫画家,她有一个奇特的爱好,就是在纸上画括号。这一天,刚刚起床的Candela画了一排括号序列,其中包含小括号()、中括号[]和大括号{},总长度为N。这排随意绘制的括号序列显得杂乱无章,于是Candela定义了什么样的括号序列是美观的:
(1) 空的括号序列是美观的;
(2) 若括号序列A是美观的,则括号序列(A)、[A]、{A}也是美观的;
(3) 若括号序列A、B都是美观的,则括号序列AB也是美观的;
例如 (){} 是美观的括号序列,而 )({)[}]( 则不是。
现在Candela想在她绘制的括号序列中,找出其中连续的一段,满足这段子序列是美观的,并且长度尽量大。你能帮帮她吗?
输入:
第一行1个整数N,第二行1个长度为N的括号序列。
各个测试点的N的大小:5,10,50,100,100,1000,1000,10000,10000,10000
输出:
一个整数,表示最长的美观的连续子序列的长度。
思路:
人都给我做傻了,搞了一上午。。。
大概就是保存上一个失败的位置,每次匹配成功就算一下这次用了多少字符,大概就是这样
对于代码:
中间有好长一节是用来测试的,tans是标准答案,ans是我算出来的答案,如果不一样我就输出一系列信息,如果最后没有输出说明代码是对的。调试的时候把数据文件复制到文件夹就行了,很方便的。
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>#define INF 0x3f3f3f3f
#define IMAX 2147483646
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned intusing namespace std;int s, n,ans;
char str[11111], st[11111];
int sta[11111];int main() {int t = 12;while (t--) {char iname[555] = "";char oname[555] = "";sprintf(iname, "sequence%d.in", t+1);sprintf(oname, "sequence%d.out", t+1);freopen(iname, "r", stdin);scanf("%s", str);n = strlen(str);ans = 0;s = 1;sta[0] = -1;st[0] = '9';for (int i = 0; i < n; i++) {if (str[i] == ')'||str[i] == '}'||str[i]==']') {if (s != 1 && ((str[i] == ')'&&st[s - 1] == '(')|| (str[i] == ']'&&st[s - 1] == '[')|| (str[i] == '}'&&st[s - 1] == '{'))) {s--;ans = max(ans, i - sta[s - 1]);}else {while (s > 1)s--;sta[0] = i;}continue;}sta[s] = i;st[s++] = str[i];}//printf("%d\n", ans);FILE *fp = fopen(oname, "r");int tans = 0;fscanf(fp, "%d", &tans);fclose(fp);if (tans != ans) printf("case:%d: %s\n %d %d\n",t+1, str , tans, ans);}return 0;
}