2021牛客寒假算法基础集训营1 B.括号
题目描述
请你构造一个非空的括号字符串,包含正好
k
k
k 个不同合法括号对。
所谓括号字符串,是指由’(‘和’)'这两种字符构成的字符串。
要求构造的字符串长度不超过
100000
100000
100000。
输入描述:
一个整数
k
k
k。
0
≤
k
≤
1
0
9
0\leq k \leq 10^9
0≤k≤109
输出描述:
一个仅包含左右括号字符串,其中有 k k k 个合法的括号对。如果有多种构造方法,输出任意一种合法方案即可。
示例1
输入
3
输出
()()
示例2
输入
4
输出
(())
示例3
输入
9
输出
()))))))))
思维题~
考虑如下的构造:
(
(
(
⋯
⏟
a
⋯
)
)
)
⏟
b
−
1
(
(
(
⋯
⏟
c
)
\underbrace{(((\cdots}_a\underbrace{\cdots)))}_{b-1}\underbrace{(((\cdots}_{c})
a
(((⋯b−1
⋯)))c
(((⋯)
显然我们要将
n
n
n 拆成
a
∗
b
+
c
a*b+c
a∗b+c (请注意为什么是
b
b
b,在最右边还有一个右括号) 的形式,因为题目限制了大小最多不超过
1
0
5
10^5
105,我们不妨默认
b
>
a
b>a
b>a,这样我们可以先求一个
a
2
a^2
a2,使得其尽可能接近
n
n
n,那么我们剩下的就是
r
e
s
=
n
−
a
2
res=n-a^2
res=n−a2,请注意此时不能直接把
r
e
s
res
res 当作
c
c
c,你可以用最大值
1
e
9
1e9
1e9 试一下发现最终的答案长度会超过
1
e
5
1e5
1e5,我们要尽可能利用已经放好的
a
a
a 个左括号,所以要再添
r
e
s
a
\frac{res}{a}
ares 个右括号,此时的
c
c
c 我们不难发现就是
r
e
s
%
a
res\%a
res%a,总答案就是
a
2
+
a
∗
⌊
r
e
s
a
⌋
+
r
e
s
%
a
=
n
a^2+a*\lfloor\frac{res}{a}\rfloor+res\%a=n
a2+a∗⌊ares⌋+res%a=n,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
vector<int> v;
for (ll i = 0; i <= 50000; i++) v.push_back(i * i);
ll n;
cin >> n;
int pos = upper_bound(v.begin(), v.end(), n) - v.begin();
ll res = n - v[pos - 1];
vector<char> ans;
for (int i = 0; i < pos - 1; i++) ans.push_back('(');
for (int i = 0; i < pos - 2; i++) ans.push_back(')');
if (n == 0) {
printf(")(");
} else {
ll cnt = res / (pos - 1);
for (int i = 0; i < cnt; i++) ans.push_back(')');
for (int i = 0; i < res % (pos - 1); i++) ans.push_back('(');
ans.push_back(')');
for (auto i:ans) cout << i;
}
return 0;
}