CF1093B Letters Rearranging 题解

Content

\(t\) 次询问,每次询问给定一个字符串 \(s\)。定义一个“好的字符串”为不是回文串的字符串。对于每一次询问,求出任意一个重新排列能够得到的“好的字符串”,或者这不可能实现。

数据范围:\(1\leqslant t\leqslant 100,1\leqslant|s|\leqslant 1000\)

Solution

首先我们来判断一下,什么样的情况下一个回文串无法变成一个非回文串?显然是这个回文串里面只有一种字符的情况下。那么其他的情况下,如何讲一个回文串变成一个非回文串?我们可以先找到中间的一个字符串(如果长度是偶数,随便取左边还是右边都行),然后开始往左扫、往右扫,一旦发现有了和当前字符不一样的字符,就将这两个字符交换,不然换了之后还是回文串。

接下来讲一下,如何判断一个字符串是否是回文串?

我们定一个左边界 \(l\) 和右边界 \(r\),规定 \(l\leqslant r\)(尤其是在字符串的长度是奇数的情况下)。那么我们可以直接往中间一起扫,一旦有两个字符串不相同,那么这个字符串就不是回文串了。如果到了中间还没有不符合条件的情况出现的话,那么这个字符串就是回文串了。

至于判断一个字符串是否只有一种字符和上面的情况类似,只要发现有两个不同的字符就不可能会是的,扫完之后如果还没有出现有不同字符的情况,那么这个字符串就只有一种字符了。

Code

int t;

int main() {
	getint(t);
	while(t--) {
		string s;
		cin >> s;
		int len = s.size(), flagno = 1, flagpa = 1, i, j;
		_for(i, 1, len - 1) if(s[i] != s[i - 1])	flagno = 0;
		for(i = 0, j = len - 1; i <= j; ++i, --j)
			if(s[i] != s[j])	flagpa = 0;
		if(flagno) {puts("-1"); continue;}
		if(flagpa) {
			int k = i;
			while(s[k] == s[i] && k < len - 1)	k++;
			if(s[k] == s[i]) {
				int k0 = i;
				while(s[k0] == s[i] && k0 > 0)	k0--;
				swap(s[k0], s[i]);
			}
			else swap(s[k], s[i]);
		}
		cout << s << endl;
	}
	return 0;
}
posted @ 2021-12-17 14:38  Eason_AC  阅读(37)  评论(0)    收藏  举报