CH1801

括号画家
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 int

using 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值