Problem D Parentheses

题目

Problem D 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 satisfies 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
12
Output for the Sample Input 1
)(
There are infinitely 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.

题目分析

对于这道题来说因为要求最短的,但是我们又知道形如)(,))((,)))(((,))))((((可以使交换次数最多并且串最短,同样我们会发现这些串的交换次数的规律1,1+2,1+2+3,1+2+3+4,1+2+3+4+5。这样对于这些数中间的数我们只需要将第一个(往左边移动即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5;
typedef long long LL;

LL f[maxn+5];

void init(){
    f[0] = 0LL;
    for(int i = 1; i < maxn; i++) f[i] = f[i-1]+i;
}

int main(){
    init();
    int n;
    while(scanf("%d", &n) != EOF){
        int i;
        for(i = 1; i < maxn; i++) if(f[i] >= n) break;
        int cnt = i - (f[i] - n);
        if(cnt != i){
            for(int j = 0; j < i; j++){
                if(j == cnt) printf("()");
                else printf(")");
            }
            for(int j = 1; j < i; j++) printf("(");
            printf("\n");
        }
        else{
            for(int j = 0; j < i; j++) printf(")");
            for(int j = 0; j < i; j++) printf("(");
            printf("\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值