Parentheses

Parentheses
Input: Standard Input
Time Limit: See AtCoder
Dave loves strings consisting only of (’ and)’. Especially, he is interested in balanced strings.
Any balanced strings can be constructed using the following rules:
A string ()” is balanced.
Concatenation of two balanced strings are balanced.
If T is a balanced string, concatenation of (’, T, and)’ in this order is balanced. For
example, ()()” and (()())” are balanced strings. )(” and )()(()” are not balanced
strings.
Dave has a string consisting only of (’ and)’. It satis es the followings:
You can make it balanced by swapping adjacent characters exactly A times.
For any non-negative integer B (B < A), you cannot make it balanced by B swaps of
adjacent characters.
It is the shortest of all strings satisfying the above conditions.
Your task is to compute Dave’s string. If there are multiple candidates, output the minimum in
lexicographic order. As is the case with ASCII, (’ is less than)’.
Input
The input consists of a single test case, which contains an integer A(1 <= A <= 109).
Output
Output Dave’s string in one line. If there are multiple candidates, output the minimum in lexicographic order.

Sample Input 1
1

Output for the Sample Input 1
)(

There are in nitely many strings which can be balanced by only one swap. Dave’s string is the shortest of them.

Sample Input 2
4

Output for the Sample Input 2
)())((

String ))(()(” can be balanced by 4 swaps, but the output should be )())((” because it is the minimum in lexicographic order.

题意:
在一个只有‘(’,‘)’的字符串中,()是平衡的,连续的平衡字符串也是平衡的,给你一个数字a,问你怎样的字符串要通过最少a次交换相邻的字符才能变为平衡的。

分析:
这题我写时一遍直接AC了,哈哈哈。。。

这种题目一看就是要慢慢列出来然后找规律:
a=1 : )(
a=2 : )()(
a=3 : ))((
a=4 : )())((
……
a=6 : )))(((
写出了这么多后,我们会发现这样一个规律,当上一个存在()时,只要将第一个()相互交换位置就可以使最少交换次数加一。当不存在()时,就在最前面加上)(即可使最小交换次数加一。
交换第一个 ()和在前面加)(可以使其字典序最小

所以现在我们可以从一开始模拟就可以求出所以的了,但是会超时。
我们还发现不存在()的情况很特殊,))(( 的最少交换次数为(2 * 3) / 2 ,)))(((的最少交换次数为(3 * 4) / 2…… 所以t个)和t个(构成的字符串最小的交换次数为(t*(t+1))/2

最后我们先求出t*(t+1)<=2*a 的最大的t,然后在进行处理就可以了。

AC代码:

#include <iostream>
using namespace std;
int main()
{
	int a ;
	while(cin >> a)
	{
		int t = 1 ;
		while(t * (t + 1) <= 2 * a) t ++ ;
		t -- ;
		if(t * (t + 1) == 2 * a) 
		 {
		 	t *= 2 ;
		 	for(int i = 1;i <= t / 2 ;i ++)
		 	 printf(")") ;
		 	for(int i = 1 ;i <= t / 2;i ++)
		 	 printf("(") ;
		 	puts("") ;
		 }
		 else 
		 {
		 	
		 	int i = 1 ;
		 	int c = a - t * (t + 1) / 2 ;
		 	for( ;i <= c ;i ++)
		 	 printf(")") ;
		 	printf("(") ;
		 	i ++ ;
		 	for( ;i <= t + 2 ;i ++)
		 	 printf(")") ;
		 	for( int i = 1 ;i <= t ;i ++)
		 	 printf("(") ;
		 	puts("") ;
		 }
	}
	return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值