[贪心]UVA10716 - Evil Straw Warts Live

Problem D: Evil Straw Warts Live

A palindrome is a string of symbols that is equal to itself when reversed. Given an input string, not necessarily a palindrome, compute the number of swaps necessary to transform the string into a palindrome. By  swap  we mean reversing the order of two adjacent symbols. For example, the string "mamad" may be transformed into the palindrome "madam" with 3 swaps:
  • swap "ad" to yield "mamda"
  • swap "md" to yield "madma"
  • swap "ma" to yield "madam"

The first line of input gives n, the number of test cases. For each test case, one line of input follows, containing a string of up to 100 lowercase letters. Output consists of one line per test case. This line will contain the number of swaps, or "Impossible" if it is not possible to transform the input to a palindrome.

Sample Input

3
mamad
asflkj
aabb

Output for Sample Input

3
Impossible
2
Gordon V. Cormack

题意:给出一个字符串,问最少通过多少次交换可以把它变成回文串。如果不能变成回文串输出impossible。

题意:完全没想出是贪心,一开始还想暴力搜索的。。智商捉急啊,各种不会做。

在移动的时候我们不妨先用点贪心的思想,每次应该先把两端的变成回文,如果我们先让两端变成回文之后,这样中间的字符在移动的时候就有可能少和1个移到两端的字符发生交换,因此这样的决策不会产生负面影响。

    接下来就是去想我们要怎样让两端变成回文的了,其中一个猜想就是如果两端字符不同,那么就固定两端之一不动,通过移动另外一个字符使两端成为回文的,而且哪种方式交换次数少就选择哪种方式。至于为什么这么做,我暂时只是感觉可以,并没有进行严谨的证明。

#include<iostream>
#include<cstring>
#include<string>

using namespace std;

int arry[30];

int main()
{
	int num;
	cin>>num;
	string str;
	getline(cin,str);
	while(num--)
		{
			cin>>str;
			int cnt=0;
			int len=str.size();
			int swaps=0;
			char ch;
			memset(arry,0,sizeof(arry));
			for(int i=0;i<len;i++)
				{
					arry[str[i]-'a']++;
				}
			for(int i=0;i<26;i++)
				{
					if(arry[i]%2) cnt++;
				}
			int i,j,k;
			int l,r;
			if(cnt<=1)
				{
					for(i=0;i<len/2;i++)
						{
							j=len-1-i;
							if(str[i]!=str[j])
								{
									for(r=j;str[r]!=str[i];r--);
									for(l=i;str[l]!=str[j];l++);
									if(l-i<j-r)
										{
											swaps=swaps+l-i;
											for(k=l;k>i;k--)
												str[k]=str[k-1];
										}
									else
										{
											swaps=swaps+j-r;
											for(k=r;k<j;k++)
												str[k]=str[k+1];
										}
								}
						}
					cout<<swaps<<endl;
				}
			else
				{
					cout<<"Impossible"<<endl;
				}
		}
	return 0;
}


你可能感兴趣的:(贪心)