Codeforces Round #527 (Div. 3) C. Prefixes and Suffixes (暴力检验)

题目链接:https://codeforces.com/problemset/problem/1092/C
题目大意:
Ivan小鬼想和你玩游戏,他挑了一个长度为n的字符串s,但是他只给你这个串的所有前缀和后缀串(2*n - 2)个。现在他要你判断每个串到底是前缀还是后缀。

解题思路:
一开始我只根据长度为n-1的串造出了一个串(还有不是原串的可能?不得其解)检验了一遍,WA17,后来我暴力造出两个疑似原串暴力检验才能过。若有一个串既可以是前缀又可以是后缀,优先归为前缀一类,在暴力检验后缀,看个数是否符合n-1.这样做万无一失。经验教训就是在时间复杂度允许,而自己的结论又不能肯定是对的情况下,暴力就暴力。

代码如下:

# include <bits/stdc++.h>

using namespace std;

int n;
map <string, int> M;
string G[205];
string l[2], str[2];
char ans[300];

void getString(){
    str[0] = l[0] + l[1][n-2];
    str[1] = l[1] + l[0][n-2];
}

bool checkPre(string str, string s){
    int i;
    for(i = 0; i < s.length() && s[i] == str[i]; ++i) ;
    if(i == s.length() && !M[s]){
        M[s]++;
        return true;
    }
    else    return false;
}

bool checkSuf(){
    int j, k;
    for(int i = 0; i < 2*n - 2; ++i){
        if(ans[i] == 'S'){
            //cout << G[i] << ' ' << str[0] << endl;
            for(j = G[i].length()-1, k = str[0].length()-1; j >= 0 && G[i][j] == str[0][k]; --j, --k)  ;
            //cout << j << endl;
            if(j != -1)  return false;
        }
    }
    return true;
}

int main(){
    std::ios::sync_with_stdio(false);
    while(cin >> n){
        int cnt = 0;
        for(int i = 0; i < 2*n - 2; ++i){
            cin >> G[i];
            if(G[i].length() == n-1)    l[cnt++] = G[i];
        }

        getString();
        cnt = 0;
        for(int i = 0; i < 2*n - 2; ++i){
            if(checkPre(str[0], G[i])){
                ans[i] = 'P';
                cnt++;
            }
            else    ans[i] = 'S';
        }
        ans[2*n-2] = '\0';
        //cout << cnt << endl;
        //cout << ans << endl;
        if(cnt != n-1 || !checkSuf()){  //还是要暴力检验后缀的
            M.clear();
            for(int i = 0; i < 2*n - 2; ++i){ //造出来的第一个串不行用第二个
                if(checkPre(str[1], G[i]))
                    ans[i] = 'P';
                else
                    ans[i] = 'S';
            }
        }
        ans[2*n-2] = '\0';
        cout << ans << endl;

        M.clear();
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值