题目地址
https://codeforces.com/problemset/problem/1832/A
题目抽象
判断一个回文串
能否重新排列成另一个
回文串
题目类型
推导
(虽然是回文串,但不归为字符串类型,因为其实没有用到字符串任何特性,换成 int 元素的数组也一样)
解题思路
题目要求原字符串经过排列组合后得到的新字符串依然是回文串
我们知道回文串的特性是:左半边的串镜像等于右半边的串
所以我们只需要考虑其中左半边的字符串就行,因为右半边的跟着镜像变化就行
因此题目就变成了:
一个字符串能否重新排列成另一个字符串
有一个猜想:只要字符串内有任意两个不同的字符,就可以重新排列成另一个字符串
证明
我们先来看看,字符串a等于字符串b意味着符合以下两个条件
- a.length == b.length
- 对于任意的 i ∈ [ 0 , l e n g t h ) i \in [0,length) i∈[0,length) 都要符合 a i = = b i a_i == b_i ai==bi
在此题中,字符串b是由字符串a重新排列而成,所以条件1必然成立
当字符串 a 内有任意两个不同的字符
a
i
a_i
ai 和
a
j
a_j
aj (
a
i
≠
a
j
a_i \ne a_j
ai=aj) 时
只需要在排列组成 b 时,使得
b
i
=
a
j
&
b
j
=
a
i
b_i = a_j \& b_j = a_i
bi=aj&bj=ai
由此可得,
a
i
≠
b
i
&
a
j
≠
b
j
a_i \ne b_i \& a_j \ne b_j
ai=bi&aj=bj ,既
a
≠
b
a \ne b
a=b
猜想证明完毕
代码
#include <bits/stdc++.h>
using namespace std;
string solve(string &s) {
int half = s.length() / 2;
for (int i = 1; i < half; i ++) {
if (s[i] != s[0]) {
return "YES";
}
}
return "NO";
}
void main() {
int T;
string s;
cin >> T;
while (T --) {
cin >> s;
cout << solve(s) << endl;
}
}