完美的代价

问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
样例输入
5
mamad
样例输出

3

java实现:


C实现:

#include 

void swap(char* a, char* b)
{
    char c = *a;
    *a = *b;
    *b = c;
}

int find(char* p, char* q)
{
    char* o = q - 1;
    while (o > p && *o != *p) o--;
    return o - p;
}

int rfind(char*p, char* q)
{
    char* o = q + 1;
    while (o < p && *o != *p) o++;
    return p - o;
}

int main()
{
    int i, j, k, len, count[26] = {0};
    char str[8000];
    scanf("%d", &len);
    scanf("%s", str);
    for (i = 0; i < len; i++)
        count[str[i]-'a']++;
    int odd = 0;
    for (i = 0; i < 26; i++)
        if (count[i] % 2 == 1)
            odd++;
    if (odd <= 1)
    {
        int change = 0;
        for (i = 0; i < len / 2; i++)
        {
            if (count[str[i]-'a'] == 1)
                break;
            count[str[i]-'a'] -= 2;
            k = find(str + i, str + len - i);
            for (j = i + k; j < len - i - 1; j++)
            {
                swap(str + j, str + j + 1);
                change++;
            }
        }
        if (i != len / 2)
        {
            for (i = len - i - 1; i > len / 2; i--)
            {
                k = rfind(str + i, str + len - i - 1);
                for (j = i - k; j > len - i - 1; j--)
                {
                    swap(str + j, str + j - 1);
                    change++;
                }
            }
        }
        printf("%d", change);
    }
    else
    {
        printf("Impossible");
    }
    return 0;
}


你可能感兴趣的:(蓝桥杯历年试题专栏)