题解:
- 找到 n - 1 长的子串一个是(假设第一个是)最长前缀,另一个是最长后缀。
- 判断假设是否正确,遍历所有子串,如果符合前缀 tot 加 1,如果 tot 不够 n - 1 或者我们假设的那个前缀从第二个开始不等于那个后缀的前 n - 2 个,也就是我们假设的前后缀倒了,比如 cdeae 和 fcdea,我们原来的假设中前缀 pre = " cdeae " 和后缀 sur = " fcdea ",这样子显然不可以,所以以上两种情况都需要交换前后缀。
- 判断就可以了,比赛时有提示,同样长度的一个是前缀一个是后缀,如果已经又一个是前缀了,那么另一个就是后缀了。
- 这里科普一个小知识:string 类不能用 scanf 读入,因为 c 不支持。
代码(参考):
代码语言:javascript复制#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;
}