小易最喜欢的单词
小易喜欢的单词具有以下特性:
1.单词每个字母都是大写字母
2.单词没有连续相等的字母
3.单词没有形如“xyxy”(这里的x,y指的都是字母,并且可以相同)这样的子序列,子序列可能不连续。
例如:
小易不喜欢"ABBA",因为这里有两个连续的’B’
小易不喜欢"THETXH",因为这里包含子序列"THTH"
小易不喜欢"ABACADA",因为这里包含子序列"AAAA"
小易喜欢"A","ABA"和"ABCBA"这些单词
给你一个单词,你要回答小易是否会喜欢这个单词(只要不是不喜欢,就是喜欢)。
输入
输入为一个字符串,都由大写字母组成,长度小于100
输出
如果小易喜欢输出"Likes",不喜欢输出"Dislikes"
测试用例举例
输入
AAA
输出
Dislikes
解题思路
第一个条件和第二个条件都可以简单判断,关键在第三个条件,子序列,由于是xyxy型,说明这个字母出现不止一次,这种序列必当出现在多次出现的字母中,所以把多次出现的字母位置记录下来,然后按照下面逻辑进行循环对比是否出现XYXY
如果出现XYXY,那么只能有以下三种情况:
- XYXY,最常规的XYXY
- XYXXY,这种也算是存在XYXY子序列
- XXYXY,这种是出现一个X后出现XYXY
我的代码中把1和2两种情况一起考虑,第3种单独考虑来判断XYXY子串
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution
{
public:
bool checkSeq(string& s)
{
char check[26][5] = { 0 };//标记每个重复字母所在位置
vector<int> flag;//标记哪几个字母有重复的
auto cur = s.begin();
while (cur != s.end())
{
if (cur[0] < 'A' || cur[0] > 'Z')
return false;//如果有不是大写字母的,返回错误
if (cur + 1 != s.end() && cur[0] == cur[1])
return false;//如果前后相同的,返回错误
if (check[cur[0] - 'A'][4] < 4)
{
check[cur[0] - 'A'][check[cur[0] - 'A'][4]] = cur - tmp.begin();
if (++check[cur[0] - 'A'][4] == 4)
return false;
if (check[cur[0] - 'A'][4] == 2)
flag.push_back(cur[0] - 'A');
}
cur++;
}
if (tmp.size() >= 4)
{
//子序列长度大于4才有判断的意义
//查找是否有XYXY型的子串
//只有有字母Y处于两个X之间,另一个Y处于X的后面的位置,那么就是XYXY
for (int i = 0; i < flag.size(); i++)
{
for (int j = 1; j < flag.size(); j++)
{
if (check[flag[j]][0] > check[flag[i]][0] && check[flag[j]][0] < check[flag[i]][1])
if ((check[flag[j]][1] > check[flag[i]][1]) || (check[j][4] > 2 && check[flag[j]][1] > check[flag[i]][2]))
return false;
if (check[j][4] > 2 && check[flag[j]][0] > check[flag[i]][1] && check[flag[j]][0] < check[flag[i]][2])
if (check[flag[j]][1] > check[flag[i]][2] || check[flag[j]][1])
return false;
}
}
}
return true;
}
};
int main()
{
string s;
Solution solve;
while (cin >> s)
{
if (solve.checkSeq(s))
cout << "Likes" << endl;
else
cout << "Dislikes" << endl;
}
return 0;
}