2021牛客寒假演算法基礎集訓營1-B題
技術標籤:演算法
2021牛客寒假演算法基礎集訓營1-B題
先直接上程式碼吧。
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
#define ll long long
int main()
{
int k;
//freopen("W:\\Programing\\testinput.txt","r",stdin);
//freopen("W:\\Programing\\outandin.txt","w",stdout);
while(scanf("%d",&k)!=EOF)
{
//printf("%d ",k);
if (k<=3)
{
if (k==0) printf("(\n");
if (k==1) printf("()\n");
if (k==2) printf("(()\n");
if (k==3) printf("()()\n" );
continue;
}
int step=sqrt(k);
//printf("sqrt==%d ",step);
int reminder=(k-step*step);//reminder表示餘數
int ans=reminder%2;//判斷還需要偶數對還是奇數對括號;
for(int i=1;i<=step;i++) printf("(");//首先輸出sqrt(k)個左括號;
int cnt=step+reminder/ 2+reminder%2;
for(int i=cnt;i>=1;i--)
{
if(i==2+ans+reminder/2) //輸出reminder/2個(
{
for(int j=1;j<=reminder/2;j++,i--)
printf("(");
i++;//自己可以除錯一下,看為什麼要多這一步
}
else if (ans==1&&i==2) printf("(");
else printf(")");
}
printf("\n");
}
return 0;
}
個人思路:
首先我們知道,每個左括號都可以和它右邊的右括號成功匹配;我們先反過來想,對於一個括號字串(僅包含(
和)
的字串)這個字串所包含的匹配括號對數就可以很容易求出來:
匹配的括號對數=所有的(左括號 *它右邊右括號的括號數量)的和;
那麼 我們就先輸出k的算術平方根個(
;接下來就是除了輸出k的算術平方根個)
還有就是如何把k-(int)sqrt(K)*(int)sqrt(K)
對括號輸出,我個人採用的方法是,首先,int cnt=step+reminder/2+reminder%2;
cnt表示還需要多少個括號,通過reminder/2
(整除!!!)計算出來在如果我用構造的括號字串的最後兩個)
和前面(
匹配的話,需要多少個(
。這裡解釋一下,為什麼是最後兩個)
?而不是三個、四個呢?因為如果用最後兩個的話,要麼可以在第sqrt(k)
個(
括號後面新增reminder/2
個(
完全匹配,要麼會少一對括號不能達到k個括號,那麼剩下的一對括號就可以通過在最後一個)
的前面新增一個(
實現。
下面舉一個例子可能會更加清楚:
15==3*3+3*2
;
我們可以先構造九對匹配的括號((()))
;就這樣,然後我們再把三個(
插入到合適的位置,
從倒數第2+reminder%2+reminder/2
個位置開始輸出(
,而且15-3*3==6
為偶數,所以最終構造為
((()((())
.
第二個例子:
19==4*4+1*2+1
同理:先構造(((())))
已經把平方數的構造出來了,接著我們需要把1個(
插入到倒數第2+reminder%2+reminder/2
個位置,這樣操作之後,還剩下一對括號,那麼再倒數第一個)
前面插入一個(
就完成了我們的構造。
具體的構造步驟可以自己輸入幾個資料,小一點吧,太大了也不好,不容易看出來;
還有最後一個問題就是程式碼裡面的i++
的問題了,簡單說一下吧;當裡裡面的for
迴圈執行完畢的時候,已經對i進行了遞減操作,但是外面的for
迴圈會再次執行一遍i–,這樣,i就多減了一次,所以必須要i++;可以自己打個斷點,觀察一下喲;
還有就是,我的程式碼裡面的` if (k<=3)
if (k<=3)
{
if (k==0) printf("(\n");
if (k==1) printf("()\n");
if (k==2) printf("(()\n");
if (k==3) printf("()()\n");
continue;
}
首先是要對k=0進行特判,因為題目要求非空,其次就是,當k=3的時候按照下面的程式碼輸出的結果是不對的,k=2和k=3的輸出結果是一樣的,這個情況比較特殊,最直接的辦法就是把k=3也給特判了。雖然這一題沒有k=3這個資料(試過了,只特判0也可以過)。但還是加上吧,畢竟追求嚴謹還是好的;
如有錯誤,歡迎指正喲