EOJ 3451. 易位构词

3 篇文章 0 订阅

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

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

Input

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

Output

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

Examples

input
unce
output
ecnu
input
aaaaaa
output
impossible
#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
#include<math.h>  
#include<vector>  
#include<map>  
#include<set>  
#include<queue>  
#include<stack>  
#include<algorithm>  
using namespace std;
#define INF 100001 

typedef struct word
{
	char w;
	int pos;
	
}Word;

bool cmp1(Word &a,Word &b)
{
	if(a.w==b.w)
		return a.pos<b.pos;
	return a.w<b.w;
}

bool cmp2(Word &a,Word &b)
{
	return a.pos<b.pos;
}

Word w[INF];
int sum[26];
char str[INF];
int main()
{
	int len,i,j;
	memset(sum,0,sizeof(sum));
	gets(str);
	len=strlen(str);
	for(i=0;i<len;i++)
	{
		w[i].w=str[i];
		w[i].pos=i;
		sum[str[i]-'a']++;
	}
	int max=sum[0];
	for(i=1;i<26;i++)
	{
		if(max<sum[i])
			max=sum[i];
	}
	if(max>len/2)
		printf("impossible\n");
	else
	{
		sort(w,w+len,cmp1);		
		char tmp[INF];
		for(i=0;i<len;i++)
			tmp[i]=w[i].w;
		for(i=0;i<len;i++)
		{
			w[i].w=i-max>=0?tmp[i-max]:tmp[i+len-max];//向右移动max位
		}
		sort(w,w+len,cmp2);
		for(i=0;i<len;i++)
			printf("%c",w[i].w);
		printf("\n");
	}
	return 0;
}

本题思路如果想到按字母排序就比较简单。对给定的字符串用结构体来表示。只要按照字母排序后的字符串中出现次数最多的字母不超过总数的一半,就能够找到易位构词,否则,输出impossible。在能找到的情况下,对排序后的字符串向右移动max位(注意此时采用的是赋值,在位置不变的情况下移动字母),最后在按照序号排序就可以了。举个例子:

输入:uexey(从左到右位置序号:0,1,2,3,4)

按字母排序后:eeuxy(从左到右位置序号:1,3,0,2,4)

向右移动max位(此处为2):xyeeu(从左到右位置序号:1,3,0,2,4

按位置排序(此时已为易位构词,和输入对应即可):exeyu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值