Kuroni and Simple Strings

Kuroni and Simple Strings

题面翻译

给定一个括号序列,求至少删除多少次使得原序列中不存在「好子序列」并输出删除方案,如果本身就没有「好子序列」则输出 0 0 0

「好子序列」的定义是长度为 2 k 2k 2k 1 ∼ k 1\sim k 1k 都为 ( k + 1 ∼ 2 k k+1\sim 2k k+12k 都是 ) 的子序列。删除操作规定每次只能选择原序列中的一个「好子序列」并删除其中的全部元素。

n ≤ 5000 n\leq 5000 n5000

题目描述

Now that Kuroni has reached 10 years old, he is a big boy and doesn’t like arrays of integers as presents anymore. This year he wants a Bracket sequence as a Birthday present. More specifically, he wants a bracket sequence so complex that no matter how hard he tries, he will not be able to remove a simple subsequence!

We say that a string formed by $ n $ characters ‘(’ or ‘)’ is simple if its length $ n $ is even and positive, its first $ \frac{n}{2} $ characters are ‘(’, and its last $ \frac{n}{2} $ characters are ‘)’. For example, the strings () and (()) are simple, while the strings )( and ()() are not simple.

Kuroni will be given a string formed by characters ‘(’ and ‘)’ (the given string is not necessarily simple). An operation consists of choosing a subsequence of the characters of the string that forms a simple string and removing all the characters of this subsequence from the string. Note that this subsequence doesn’t have to be continuous. For example, he can apply the operation to the string ‘)()(()))’, to choose a subsequence of bold characters, as it forms a simple string ‘(())’, delete these bold characters from the string and to get ‘))()’.

Kuroni has to perform the minimum possible number of operations on the string, in such a way that no more operations can be performed on the remaining string. The resulting string does not have to be empty.

Since the given string is too large, Kuroni is unable to figure out how to minimize the number of operations. Can you help him do it instead?

A sequence of characters $ a $ is a subsequence of a string $ b $ if $ a $ can be obtained from $ b $ by deletion of several (possibly, zero or all) characters.

输入格式

The only line of input contains a string $ s $ ( $ 1 \le |s| \le 1000 $ ) formed by characters ‘(’ and ‘)’, where $ |s| $ is the length of $ s $ .

输出格式

In the first line, print an integer $ k $ — the minimum number of operations you have to apply. Then, print $ 2k $ lines describing the operations in the following format:

For each operation, print a line containing an integer $ m $ — the number of characters in the subsequence you will remove.

Then, print a line containing $ m $ integers $ 1 \le a_1 < a_2 < \dots < a_m $ — the indices of the characters you will remove. All integers must be less than or equal to the length of the current string, and the corresponding subsequence must form a simple string.

If there are multiple valid sequences of operations with the smallest $ k $ , you may print any of them.

样例 #1

样例输入 #1

(()((

样例输出 #1

1
2
1 3

样例 #2

样例输入 #2

)(

样例输出 #2

0

样例 #3

样例输入 #3

(()())

样例输出 #3

1
4
1 2 5 6

提示

In the first sample, the string is ‘(()((’. The operation described corresponds to deleting the bolded subsequence. The resulting string is ‘(((’, and no more operations can be performed on it. Another valid answer is choosing indices $ 2 $ and $ 3 $ , which results in the same final string.

In the second sample, it is already impossible to perform any operations.

#include<stdio.h>
#include<string.h>
int main(void)
{
	char s[1001] = { 0 };
	scanf("%s", s );
	int left = -1, right = strlen(s);
	int xuhao[1000][2] = { 0 }; int i = 1,caozuocishu=0;
	while (left<right)
	{
		while (left<right)
		{
			if (s[++left] == '(')
			{
				xuhao[i++][1] = left+1;
				break;
			}
		}
		while (left<right)
		{
			if (s[--right] == ')')
			{
				xuhao[i-1][2] = right +1;
				caozuocishu++;
				break;
			}
		}
	}
	if (caozuocishu)
	{
		printf("1\n%d\n", 2 * caozuocishu);
		for (int i = 1; i <= caozuocishu; i++)
		{
			printf("%d ", xuhao[i][1]);
		}
		for (int i = caozuocishu; i >=1; i--)
		{
			printf("%d ", xuhao[i][2]);
		}
	}
	else
	{
		printf("0");
	}

	return 0;
}

事实上最小次数为1或者0
双指针
逆向思考 最后的状态只能为若干((或若干))或者若个个)和若干(。之前每次取的个数(与)相等。那么上一次就可以一次取光光。1次自然是最小的,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值