牛客寒假集训赛01B 括号
要求构造非空字符串,包含k个合法不同合法括号对,即只由“(”“)”组成的字符串
思路:
要求有效个括号对并且长度低于1e5,题目的k最大为1e9,所以需要使用n^2 级别的括号,如“((()))”中的括号对为3^2=9,,若出现开方结果不为整数则将开方数再平方后算出相差数,若过大则继续开方并在相应位置插入括号(防止超过长度要求),反之则在字符串的第二位置插入,如“((()))”在第二位置插入2个“)”,即“( ))(()))”,此时就多出了两个括号对。
题解如下:
- 对k开方,设开方数为p(整数),如果p^2=k,则直接按顺序输出p个“(”与p个“)”。
- 若p^2!=k则用循环多次对p开方(设为x),在(1)的基础上每次开方就在字符串下标为x位置插入x个“)”,当x小于某个较小的值时在字符串的第二位置插入x个“)”。
注意事项:
一定要看k 的范围,题中为0-1e9,当k等于0时,题目不允许输出空串,所以需要随便构造一个没有合法括号的括号字符串,如“)))(((”。
要注意字符串长度。
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define endl '\n'
typedef long long ll;
using namespace std;
const int inf=0x3f3f3f3f;
const int N=2e5+5;
int main()
{
int k;
cin>>k;
if(k==0)
{
cout<<")("<<endl;
return 0;
}
int n=sqrt(k);
if(n*n==k)
{
string a="";
for(int i=1;i<=n;i++)
{
a+="(";
}
for(int i=1;i<=n;i++)
{
a+=")";
}
cout<<a;
}else{
int x=k-n*n;
string a="";
for(int i=1;i<=n;i++)
{
a+="(";
}
for(int i=1;i<=n;i++)
{
a+=")";
}
while(x>100)
{
int p=sqrt(x);
a.insert(p,p,')');
x-=p*p;
}
if(x!=0)
{
a.insert(1,x,')');
}
cout<<a;
}
return 0;
}
(这寒假特训营根本就不是给萌新出的!我这个蒟蒻就A了两个 QAQ)
浙公网安备 33010602011771号