牛客寒假集训赛01B 括号

传送门

要求构造非空字符串,包含k个合法不同合法括号对,即只由“(”“)”组成的字符串

思路:

要求有效个括号对并且长度低于1e5,题目的k最大为1e9,所以需要使用n^2 级别的括号,如“((()))”中的括号对为3^2=9,,若出现开方结果不为整数则将开方数再平方后算出相差数,若过大则继续开方并在相应位置插入括号(防止超过长度要求),反之则在字符串的第二位置插入,如“((()))”在第二位置插入2个“)”,即“( ))(()))”,此时就多出了两个括号对。

题解如下:

  1. 对k开方,设开方数为p(整数),如果p^2=k,则直接按顺序输出p个“(”与p个“)”。
  2. 若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)

posted on 2021-02-01 22:01  鬼人明灯  阅读(54)  评论(0)    收藏  举报