Peculiar Movie Preferences (Codeforces 1629D)
Tags: Greedy, strings

Mihai plans to watch a movie. He only likes palindromic movies, so he wants to skip some (possibly zero) scenes to make the remaining parts of the movie palindromic.You are given a list $$$s$$$ of $$$n$$$ non-empty strings of length at most $$$3$$$, representing the scenes of Mihai's movie.A subsequence of $$$s$$$ is called awesome if it is non-empty and the concatenation of the strings in the subsequence, in order, is a palindrome.Can you help Mihai check if there is at least one awesome subsequence of $$$s$$$?A palindrome is a string that reads the same backward as forward, for example strings "z", "aaa", "aba", "abccba" are palindromes, but strings "codeforces", "reality", "ab" are not.A sequence $$$a$$$ is a non-empty subsequence of a non-empty sequence $$$b$$$ if $$$a$$$ can be obtained from $$$b$$$ by deletion of several (possibly zero, but not all) elements.

Input: The first line of the input contains a single integer $$$t$$$ ($$$1 \le t \le 100$$$) — the number of test cases. The description of test cases follows.The first line of each test case contains a single integer $$$n$$$ ($$$1 \le n \le 10^5$$$) — the number of scenes in the movie.Then follows $$$n$$$ lines, the $$$i$$$-th of which containing a single non-empty string $$$s_i$$$ of length at most $$$3$$$, consisting of lowercase Latin letters.It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$10^5$$$.

Output: For each test case, print "YES" if there is an awesome subsequence of $$$s$$$, or "NO" otherwise (case insensitive).

Note: In the first test case, an awesome subsequence of $$$s$$$ is $$$[ab, cc, ba]$$$

Sample Inputs:
6
5
zx
ab
cc
zx
ba
2
ab
bad
4
co
def
orc
es
3
a
b
c
3
ab
cd
cba
2
ab
ab

Sample Outputs:
YES
NO
NO
YES
YES
NO

Solution (Python):
def solve():
    n = int(input())
    seen = set()
    seen3 = set()
    seentotal = set()
    flag = False
    for _ in range(n):
        s = input()
        if len(s) == 1:
            flag = True
        elif len(s) == 2:
            if s[0] == s[1]:
                flag = True
            elif s[1] + s[0] in seen:
                flag = True
            elif s[1] + s[0] in seen3:
                flag = True
            seen.add(s)
        else:
            if s[0] == s[-1]:
                flag = True
            elif s[-1] + s[-2] in seen:
                flag = True
            elif s[::-1] in seentotal:
                flag = True
            seen3.add(s[:2])
            seentotal.add(s)
    print('YES') if flag else print('NO')
for i in range(int(input())):
    solve()

Solution (Python):
import sys
input = sys.stdin.readline
num_test_cases = int(input())
for test_case_ittr in range(num_test_cases):
    n = int(input())
    scenes = [input().strip() for i in range(n)]
    seen_twos = set()
    seen_threes = set()
    seen_prefixes = set()
    can_make_palindrome = 'NO'
    for x in scenes:
        reverse = x[::-1]
        if x == reverse:
            can_make_palindrome = 'YES'
            break
        if len(x) == 2:
            if reverse in seen_twos or reverse in seen_prefixes:
                can_make_palindrome = 'YES'
                break
            seen_twos.add(x)
        elif len(x) == 3:
            if reverse in seen_threes or reverse[:-1] in seen_twos:
                can_make_palindrome = 'YES'
                break
            seen_threes.add(x)
            seen_prefixes.add(x[:-1])
    print(can_make_palindrome)

Solution (Python):
def solve():
    n = int(input())
    s = set()
    s2 = set()
    flg = 0
    for i in range(n):
        x = input()
        if flg == 1:
            continue
        n = len(x)
        xr = x[::-1]
        if x == xr or xr in s or n == 1:
            flg = 1
        if n == 2:
            if xr in s2:
                flg = 1
        if n == 3:
            if xr[:2] in s:
                flg = 1
            s2.add(x[:2])
        s.add(x)
    if flg == 0:
        print('NO')
    else:
        print('YES')
t = int(input())
while t:
    solve()
    t -= 1
''