1. 程式人生 > >C. Prefixes and Suffixes ( Codeforces Round #527 (Div. 3) )

C. Prefixes and Suffixes ( Codeforces Round #527 (Div. 3) )


題意:給你一個 n 長度的字串,給你 2n - 2 個子串,其中有 n - 1 個字首和 n - 1 個字尾,輸出一個合法的判斷。


題解:

  1. 找到 n - 1 長的子串一個是(假設第一個是)最長字首,另一個是最長字尾。

  2. 判斷假設是否正確,遍歷所有子串,如果符合字首 tot 加 1,如果 tot 不夠 n - 1 或者我們假設的那個字首從第二個開始不等於那個字尾的前 n - 2 個,也就是我們假設的前後綴倒了,比如 cdeae 和 fcdea,我們原來的假設中字首 pre = " cdeae " 和字尾 sur = " fcdea ",這樣子顯然不可以,所以以上兩種情況都需要交換前後綴。

  3. 判斷就可以了,比賽時有提示,同樣長度的一個是字首一個是字尾,如果已經又一個是字首了,那麼另一個就是字尾了。

  4. 這裡科普一個小知識:string 類不能用 scanf 讀入,因為 c 不支援。


程式碼(參考):

#include <bits/stdc++.h>

using namespace std;

string s[500];
bool vis[500];

int main()
{
    int n;
    bool flag = true;
    string pre, sur;
    string ans;
    scanf("%d", &n);
    for(int i = 1; i <= 2 * n - 2; i ++)
    {
        cin >> s[i];
        if(flag && (s[i].size() == (n - 1)))
        {
            pre = s[i];

            flag = false;
        }
        else if(s[i].size() == (n - 1)){
            sur = s[i];
        }
    }

    int tot = 0;

    for(int i = 1; i <= 2 * n - 2; i ++)
    {
        if(s[i][0] == pre[0]) tot ++;
    }

    if(tot < n - 1 || pre.substr(1) != sur.substr(0, n - 2))
    {
        swap(pre,sur);
    }

    memset(vis,false,sizeof(vis));

    for(int i = 1; i <= 2 * n - 2; i ++)
    {
        if(pre.substr(0,s[i].size())== s[i] && !vis[s[i].size()])
        {
            vis[s[i].size()] = true;
            ans += "P";
        }
        else ans += "S";
    }
    cout << ans << endl;
    return 0;
}