[贪心]UVA10716 - Evil Straw Warts Live

来源:互联网 发布:linux是用什么语言写的 编辑:程序博客网 时间:2024/06/06 04:16

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

3mamadasflkjaabb

Output for Sample Input

3Impossible2

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;}


1 0
原创粉丝点击