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
描述:
判断一个字符串是否可以经过字符交换转化为回文字符串。
方法:
先统计字符串中各个字符的出现的次数和个数是奇数的字符个数。找出字符串的长度L。如果奇数字符大于1个,返回-1.
从左往右遍历字符串(到长度的一半L/2),对每一个字符
如果其个数大于1,则从字对称位置向头遍历,直到找到第一个相同字符,然后把它移动到对称位置。并记录移动次数,相应字符个数减少2。
如果其个数等于1,与下一个字符交换位置,并重新处理该位置的新字符。记录移动次数(+1)。
代码:
#include #include void swap(char str[], int x, int y) { char t = str[x]; int i; for(i = x; i < y; i++) str[i] = str[i+1]; str[y] = t; } int num_of_swap(char str[]) { int nl[26], len, i, j, t, n, m; len = strlen(str); for(i = 0; i < 26; i++) nl[i] = 0; for(i = 0; i < len; i++){ nl[str[i]-'a']++; } t = 0; for(i = 0; i < 26; i++){ if(nl[i] & 1) t++; } if(t > 1 || ((len & 1) == 0 && t == 1)) return -1; n = 0; m = len/2; for(i = 0; i < m; i++){ if(nl[str[i]-'a'] > 1){ for(j = len-1-i; j >= i; j--){ if(str[j] == str[i]){ n += len-1-i-j; swap(str, j, len-1-i); nl[str[i]-'a'] -= 2; break; } } } else if(nl[str[i]-'a'] == 1){ n++; swap(str, i, i+1); i--; } } return n; } int main() { char str[101]; int n, k; scanf("%d", &n); while(n-- > 0){ scanf("%s", str); k = num_of_swap(str); if(k == -1) printf("Impossible\n"); else printf("%d\n", k); } return 0; }