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;
}