Official

C - racecar Editorial by mechanicalpenciI


基本的には問題文の指示に従って、 \(1\leq i,j\leq N\) をみたす \(i,j\) に対して、

  1. \(i\neq j\) であるか判定する。
  2. 1.の条件をみたしているとき、\(S_i\)\(S_j\) を連結した文字列\(T_{i,j}\equiv S_i+S_j\) を作る。
  3. (1.の条件をみたしているとき、)\(T_{i,j}\) が回文であるか判定する。具体的には、\(1\leq k\leq \lvert T_{i,j}\rvert\) をみたすすべての整数 \(k\) について、\(T_{i,j}\)\(k\) 文字目と \( \lvert T_{i,j}\rvert+1-k\) 文字目が同一か判定する。

ということを行い、一度でも \(T_{i,j}\) が回文であれば Yes 、そうでなければ No を出力すれば良いです。

if 文と for文および 文字列の長さを得る方法や文字列を連結する方法が分かっていればこれを実装する事ができます。

愚直に行っても計算量は \(O(N^2\max(\lvert S_i\rvert))\) 程度のため、十分高速にこの問題を解く事ができます。

c++ による実装例:

#include <bits/stdc++.h>
using namespace std;


int main() {
	int n,l;
	bool flag;
	string s[100];
	string t;

	cin>>n;
	for(int i=0;i<n;i++)cin>>s[i];

	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(i!=j){
				t=s[i]+s[j];
				l=t.size();
				flag=true;
				for(int k=0;k<l;k++)if(t[k]!=t[l-k-1])flag=false;
				if(flag){
					cout<<"Yes"<<endl;
					return 0;
				}
			}
		}
	}

	cout<<"No"<<endl;
	return 0;
}

Python による実装例:

n=int(input())
s=[input() for i in range(n)]
ans="No"

for i in range(n):
    for j in range(n):
        if i!=j:
            t=s[i]+s[j]
            flag=True
            for k in range(len(t)):
                if t[k]!=t[-k-1]:
                    flag=False
            if flag:
                ans="Yes"

print(ans)

posted:
last update: