1. 程式人生 > >$Codeforces; Round; 504; (Div.2)$

$Codeforces; Round; 504; (Div.2)$

char s pil bre return toys pac 修改 ring algo

賓館的\(\rm{wifi}\)也太不好了,蹭的\(ZZC\)的熱點才打的比賽(感謝\(ZZC\)

日常掉rating…… 我現在是個\(\color{green}{pupil}\)……

因為我菜,所以還是只寫了前三道題


題解

\(\mathcal{A.Single\; Wildcard\; Pattern\; Matching}\)

題目大意:有點長,不想翻譯了qwq

我能說第一題是前三道題中最難的麽……各種特判,各種被卡,最後交了4遍也沒做出來(我太蒟了 QAQ)

反復修改後的冗雜的AC代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int n,m; cin>>n>>m; n-=1,m-=1;
    if(n>m+1){
        cout<<"NO"; return 0;
    }
    char s1[200010],s2[200010]; cin>>s1>>s2;
    int pos=0;
    for(int i=0;i<=n+1;i++){
        pos=i;
        if(s1[i]=='*') break;
    }
    //cout<<pos;
    for(int i=0;i<pos;i++){
        if(s1[i]!=s2[i]){
            cout<<"NO"; return 0;
        }
    }
    if(pos==n+1){
        if(n!=m){
            cout<<"NO"; return 0;   
        }
        goto hhh;
    }
    int j;
    for(j=0;;j++){
        if(n-j==pos) break;
        if(s1[n-j]!=s2[m-j]){
            cout<<"NO"; return 0;
        }
    }
    for(int i=pos;i<m-j;i++){
        if(s2[i]<'a'||s2[i]>'z'){
            cout<<"NO"; return 0;
        }
    }
    hhh:
    cout<<"YES";
    return 0;
}

\(\mathfrak{B.Pair\; of\; Toys}\)

題目大意:輸入兩個數\(n,k\),問從\(1\text{~}n\)中取出\(2\)個數使得它們的和為\(k\)的方案數(\((a,b)\)\((b,a)\)算同一種方案)

這題算是數論吧……挺簡單的

如果\(a+b==k\),那麽\((a+1)+(b-1),(a+2)+(b+2)\)……也等於\(k\)。所以我們可以找到最接近的兩個數\(k/2,k/2+1\),然後\(1\text{~}k/2\)\((k/2+1)\text{~}(k{-}1)\)就是所有的方案。接下來我們只需要找出合法的方案數就可以了

首先我們可以確定如果\(k/2{>=}n\)

,肯定無解,當\(k/2{<}n\)的時候,因為\(n\)可能小於\(k\),所以合法的方案數應為\(\min(k/2,(k-1)-k/2,n-k/2)\)

P.S. 不要忘了開\(long\; long\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    long long n,k; cin>>n>>k;
    long long mid=k/2,ans;
    if(mid<n) ans=min(mid,min(k-1-mid,n-mid));
    else{
        cout<<0; return 0;
    }
    cout<<ans;
    return 0;
}

\(\sf{C.Bracket\; Subsequence}\)

題目大意:給你一個長度為\(n\)括號序列\(a\),找出一段長度為\(m\)合法的括號序列\(b\),使得\(b\)\(a\)的子串

\(b\)為答案,我們枚舉\(a\)的每一個括號,每掃到一個括號,就把它加入\(b\)裏,如果為左括號,\(cnt{+}{=}1\),如果\(cnt==m/2\)就跳出循環,然後從後面補右括號就行了

沒初始化\(ans\)數組,FST了…… QAQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int n,m; cin>>n>>m; m/=2;
    char a[200010],b[200010]; cin>>a;
    memset(b,0,sizeof(b));
    int len=strlen(a)-1,tot=0,cnt=0;
    for(int i=0;i<=len;i++){
        if(a[i]=='('){
            b[tot++]='(';
            cnt++;
        }
        if(cnt==m) break;
        if(a[i]==')'){
            b[tot++]=')';
        }
    }
    for(int i=tot;i<m*2;i++) b[i]=')';
    cout<<b;
    return 0;
}

總結

這次比賽暴露了我以下幾個問題:

  1. 不夠認真、仔細,對特殊情況考慮不全
  2. 代碼中總存在一些小問題
  3. 太浮躁,認為第一遍測試過了就萬事大吉了,沒有檢查代碼的隱藏\(bug\)
  4. 太過依賴於樣例和測試數據

$Codeforces\; Round\; 504\; (Div.2)$