题目大意
构造一个非空的括号字符串,包含正好 k , k ≤ 1 e 9 k, k \leq 1e9 k,k≤1e9 个不同合法括号对。所谓括号字符串,是指由’ ( ( (‘和’ ) ) )'这两种字符构成的字符串。要求构造的字符串长度不超过100000。
解题思路
这题折磨了好久,一开始想的方法是将一个数分解为两个因子相乘,但是显然最坏的结果是2乘上一个大质数,那么肯定翻车。然后想到先找 k \sqrt{k} k,令 k = k ∗ k + r e s k = \sqrt{k}*\sqrt{k} + res k=k∗k+res,然后分解 r e s res res凑出结果,可是考虑一些极端的情况还是会爆长度。
实际上在考虑到对 k k k开根号时就想偏了,只需要看需要多少个 k \sqrt{k} k,然后将所有余数和最后一个右括号凑一起。这样最坏的情况是 3 ∗ 1 e 9 = 9 e 4 3*\sqrt{1e9} = 9e4 3∗1e9=9e4,刚好可以。
PS:注意特判 k = 0 k=0 k=0的情况。
//
// Created by Happig on 2021/2/1.
//
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define ENDL "\n"
#define lowbit(x) (x & (-x))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double dinf = 1e300;
const ll INF = 1e18;
const int Mod = 1e9 + 7;
const int maxn = 2e5 + 10;
string ans;
int main() {
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int k;
cin >> k;
if (k == 0) {
cout << "(" << ENDL;
return 0;
}
ans = "";
int x = sqrt(k);
int y = k / x, z = k % x;
for (int i = 1; i <= y; i++) ans += '(';
for (int i = 1; i < x; i++) ans += ')';
for (int i = 1; i <= z; i++) ans += '(';
ans += ')';
cout << ans << ENDL;
return 0;
}