2021牛客寒假算法基础集训营1

本文探讨如何高效地构造含有k个合法括号对的字符串,通过优化算法,确保字符串长度不超过10万,同时保持左右括号对的平衡。方法包括巧妙利用数学计算和字符串操作技巧,提供了一个高效的代码实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

B-括号

## 题目描述

请你构造一个非空的括号字符串,包含正好 k 个不同合法括号对。
所谓括号字符串,是指由’(‘和’)'这两种字符构成的字符串。
要求构造的字符串长度不超过100000。
输入描述:
一个整数 k。
一个整数 kk。
0≤k≤1e9

输出描述:
一个仅包含左右括号字符串,其中有 kk 个合法的括号对。如果有多种构造方法,输出任意一种合法方案即可。
示例1
输入
3
输出
()()
说明
假设字符串数组下标从 1 开始,则 (1,2), (1,4), (3,4) 共计 3 个合法括号对
当然,"()))" 也是一种合法的构造
示例2
输入
4
输出
(())
说明
假设字符串数组下标从 1 开始,则 (1,3), (1,4), (2,3), (2,4) 共计 4 个合法括号对
另外,合法的构造还有"())()"、"()(()(" 等等。。
示例3
输入
9
输出
()))))))))
说明
合法的还可以是:
())())()
((()))
)()()())(
等等等。。有非常多种合法构造,输出任意即可。
## 题目思路
1.先看数据范围,0<=k<=1e9,字符串长度不超过100000。直接输出必然爆掉,所以想办法优化。先输出50000个“)”,然后再计算a=k/50000,有多少a就在这50000个“)”的最左边加几个“(”。然后计算b=k%50000,再在从右往左数第b个位置插入“(”。由于a的最大值就是20000(k=1e9时),长度最多是7e4,必然不会超出范围。
2.1中是a=k/50000,并且是先甩50000个“)”出来,但暴力且无脑(尽管暴力已经可以AC了)。若要想让字符串左右尽量平衡,可以先画根号a个“)”出来。然后将b=k/(根号a(取下限))个“(”放在最左边,最后将零头c=k%b(k=p*(k/(根号a(取下限)))+c,p=根号a取下限)补上,道理与1相同,但是字符串更对称了。例如23,根号23=4,右边先放4个“)”,然后左边b=23/4=5,现在一共有5*4=20个括号,再从右往左数第23%5==3个位置插入“(”。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<cmath>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<map>
using namespace std;
#define ll long long
const int N=1e6+7;
const int INF = 0x3f3f3f3f;
int k;
//map<int,int,greater<int> > a;
int main()
{
    int n,a,b;
    scanf("%d",&k);
    a=k/50000;
    b=k%50000;
    for(int i=0;i<a;i++){
        printf("(");
    }
    for(int i=0;i<=49999;i++){
        if(50000-i==b){
            printf("()");
        }else{
            printf(")");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值