题目链接: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;
}