3451. 易位构词

单点时限: 2.0 sec

内存限制: 256 MB

易位构词 (anagram),指将一个单词中的字母重新排列,原单词中的每个字母都出现有且仅有一次。例如 “unce” 可以被易位构词成 “ecnu”。在某些情况下,要求重排而成的依然是一个单词,但本题没有这种要求,因为我们根本没有词典。

我们所感兴趣的是,有些单词中的字母进行适当的重排后,可以使得构成的单词每个对应的位置上字母都不一样。例如 “unce” 和 “ecnu”,就有 “u” ≠ “e”, “n” ≠ “c”, “c” ≠ “n”, “e” ≠ “u”。现在给出一个单词,问是否存在这样一个重排。

在这里插入图片描述

输入格式
一行一个单词 s (1≤|s|≤105)。单词完全由 26 个小写英文字母构成。

输出格式
输出一个单词。如果有多解,输出任意解。如果不存在,输出 impossible。

样例
input
unce
output
ecnu
input
aaaaaa
output
impossible

/*
思路:先考虑字符串有序的情况,比如是 aaabcc,只要将字符串右移 3 位,变成 bccaaa。那么对于无序的情况,我们可以通过排序让它有序,做完之后再按照原先字符位置排回去。
显然最多的字母出现次数大于一半的情况是不行的。否则就将每个字母的位置和字母绑定一下,按字母序对结构体进行排序。然后以字符频率最多右移后,按原来位置派回去。即:s[c[i].num]=c[(i+Max)%len].c
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct C {
	char c;
	int num;
};
bool cmp(C a,C b)
{
	return a.c<b.c;
}
int main() {
	int flag[26]= {0};
	string s;
	cin>>s;
	int len=s.size();
	C c[len];
	int Max=0;
	for(int i=0; i<len; i++) {
		flag[s[i]-'a']++;
		c[i].c=s[i];
		c[i].num=i;
		Max=max(Max,flag[s[i]-'a']);
		if(Max>s.size()/2)
		{
			cout<<"impossible"<<endl;
			return 0;
		}
	}
	sort(c,c+len,cmp);
	for(int i=0; i<len; i++)
		s[c[i].num]=c[(i+Max)%len].c;//移位x 按原来位置排列
	cout<<s;
}
发布了45 篇原创文章 · 获赞 21 · 访问量 475

猜你喜欢

转载自blog.csdn.net/qq_40394960/article/details/105138725