菜菜

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题意:输入长度在100内的小写字母的字符串,求把它变成回文字符串的最少交换次数.如果不能变成回文串,输入,Impossible.

解法:

要变成回文字符串,必须满足一个性质,所有的字符出现次数都是偶数,或者只有一个字符是奇数,

每次取俩端的字符,计算一下,那个花费低就选那个,注意,如果字符串长度是奇数,并且俩端某个字符应该是放在中间的位置,那么它的花费肯定是无穷大.

可以证明,如果我们s1.....e1......s2.....e2能够保证从s1-e1,e2-s2都是回文的字符串,那么放在中间的那个字符最后肯定会在中间.

#include <string>
#include<iostream>
#include<map>
#include<memory.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<math.h>
#include<iomanip>
#include<bitset>

namespace cc
{
    using std::cout;
    using std::endl;
    using std::cin;
    using std::map;
    using std::vector;
    using std::string;
    using std::sort;
    using std::priority_queue;
    using std::greater;
    using std::vector;
    using std::swap;
    using std::stack;
    using std::bitset;


    constexpr int N = 10010;

    string str;
    bool check()
    {
        int a[26] = { 0 };
        int odd = 0;
        for (int i = 0;i < str.length();i++)
        {
            a[str[i] - 'a']++;
        }
        for (int i=0;i<26;i++)
        {
            if (a[i] % 2 == 1)
            {
                odd++;
                if (odd == 2)
                    return false;
            }
        }
        return true;
    }
    void solve()
    {
        int n;
        cin >> n;
        while (n--)
        {
            cin >> str;
            if (!check())
            {
                cout << "Impossible" << endl;
                continue;
            }
            int s = 0, e = str.length()-1;
            int total = 0;
            //e是最后一个元素
            while (s < e) 
            {
                if (str[s] == str[e])
                {
                    ++s;
                    --e;
                    continue;
                }
                int index1 = -1;
                int s1 = 0;
                for (int i=e;i > s; i--)
                {
                    if (str[i] == str[s])
                    {
                        index1 = i;
                        break;
                    }
                }
                if (index1 == -1)
                {
                    s1 = INT32_MAX;
                }
                else
                    s1 = e - index1;
                int index2 = -1;
                int s2 = -1;
                for (int i=s;i < e;i++) 
                {
                    if (str[i] == str[e])
                    {
                        index2 = i;
                        break;
                    }
                }
                if (index2 == -1)
                {
                    s2 = INT32_MAX;
                }
                else
                    s2 = index2 - s;
                if (s2 < s1) 
                {
                    //select e 
                    for (int i=index2;i>s;i--) 
                    {
                        swap(str[i],str[i-1]);
                        ++total;
                    }
                }
                else
                {
                    //select s
                    for (int i=index1;i<e;i++) 
                    {
                        swap(str[i],str[i+1]);
                        ++total;
                    }
                    
                }
                --e;
                ++s;
            }
            cout << total << endl;
        }
    }

};


int main()
{

#ifndef ONLINE_JUDGE
    freopen("d://1.text", "r", stdin);
#endif // !ONLINE_JUDGE
    cc::solve();
    return 0;
}

 

posted on 2018-12-22 16:38  好吧,就是菜菜  阅读(217)  评论(0编辑  收藏  举报