题意:输入一串字符,不必要是回文的,计算需要交换多少次能把它变成回文的(所谓的交换是指交换相邻的两个字符)。
方法:贪心、模拟。
1、judge了三种情况,字母全是偶数个数;有一个字母是单数;有两个及以上字母是单数。
2、移动的时候注意循环的理解。
AC代码:
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
#include <ctime>
using namespace std;
const int maxn = 100+5;
void swap(char *a, char *b)
{
char t;
t = *a;
*a = *b;
*b = t;
}
int Judge(char s[])
{
int w[26+2], i = 0, flag_odd = 0, count_odd = 0;
memset(w, 0, sizeof(w));
for (i = 0; i < strlen(s); i++)
++w[s[i] - 'a'];
for (i = 0; i < 26; i++)
{
if (w[i] % 2)
{
flag_odd = i+1;
count_odd++;
}
}
if (count_odd > 1)
return 0;
else if (0 == count_odd)
return 100;
else
return flag_odd;
}
int main()
{
#ifdef Local
freopen("a.txt", "r", stdin);
#endif
int t = 0;
cin >> t;
getchar();
while (t--)
{
char s[maxn];
int flag = 0, len = 0, i = 0, j = 0, count = 0;
gets(s);
len = strlen(s);
flag = Judge(s);
if (!flag)
{
cout << "Impossible" << endl;
}
else
{
char c = '*';
int num_c = 0;
if (flag < 100)
{
c = flag + 'a' - 1;
for (i = 0; i < len; i++)
if (s[i] == c)
num_c++;
if (num_c > 1)
{
int temp_num = 0;
for (i = 0, temp_num = 0; i < len; i++)
if (s[i] == c)
{
if (temp_num == num_c / 2)
{
s[i] = '*';
c = '*';
break;
}
else
temp_num++;
}
}
}
for (i = 0; i < len / 2; i++)
{
if (s[i] == c)
{
swap(&s[i], &s[i+1]);
++count;
}
if (s[i] != s[len-i-1])
{
for (j = len-i-1; j >= i+1; j--)
if (s[i] == s[j])
break;
for (int k = j; k < len-i-1; k++)
{
swap(&s[k], &s[k+1]);
++count;
}
}
}
cout << count << endl;
}
}
return 0;
}
WA是这没计数。
if (s[i] == c)
{
swap(&s[i], &s[i+1]);
++count;
}