1. 程式人生 > 其它 >2021牛客寒假演算法基礎集訓營1-B題

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也可以過)。但還是加上吧,畢竟追求嚴謹還是好的;

如有錯誤,歡迎指正喲