毛头小子


私信TA

用户名:uq_10571446592

访问量:561

签 名:

救赎未来的自己!

等  级
排  名 28366
经  验 536
参赛次数 0
文章发表 8
年  龄 0
在职情况 学生
学  校
专  业

  自我简介:

解题思路:
首先判断字符串能否构成回文,回文的本质是对称;

1、对于字符个数为偶数的字符串,所有的字母都是成偶数出现的,如果不是,直接输出Impossible

2、对于字符个数是奇数的字符串,有且仅有中间的一个字母数量为奇数(数量不一定为1),如果个数为奇数的字母数量出现一个以上,直接输出Impossible

接下来就是数交换的次数:

例如:aaabbccddee(以奇数为例,偶数类似)

总共有11个字符,且能构成回文,首先需要明白,若所有字母移动的次数最小,那么和就是最小的,先对整个构成回文的思路有一个初步的理解后,我们再来理解一下为什么和最小的原因;

在不考虑移动次数的情况下,我们如果要构成回文,那么只需以一边为标准即可,这里以左边为标准,改变右边的字母,看例子:

左边第一个字母为a,那么右边的最后一个字母也应为a,此时从右往左找,找到第一个与a相同的字母,移动到相应的位置,然后继续相同的步骤,这里先明白构成回文的基本方法,多出来的a会在考虑最小移动次数的情况下自然解决;

现在考虑最小移动次数,此时的回文标准是不固定的,有可能是以左边为标准,也有可能是以右边为标准,目的都是为了获得最小移动次数,此时,当我们以左边为标准寻找字母时,势必会找到一个相同的字母,且能知道移动的次数,然后把标准放到右边,同一个对称位置,如下图,从左边向右寻找,势必会找到一个相同的字


位置1位置2(第一次标准)34……………………43位置2(第二次标准)位置1

母,且能知道需要移动的次数,那么我们需要移动的是次数较小的字母,对于那些非移动目标的字母,虽然被移动了,但都是向中间靠,所以对最终结果没有影响。现在来理解最小的原因,对于一个移动字母,直接从当前的位置向目标位置靠是移动次数最小的,在我们构成回文的过程中,以abcdefaccb为例(不用在意是否构成回文,只是为了做一个更加形象的解释),以左a为标准,abcdefaccb,从右往左找abcdefaccb<—,找到第一个a,abcdefaccb,移动次数为3,以右b为标准abcdefaccb,从左往右找,—>abcdefaccb,找到第一个b,abcdefaccb,移动次数为1,应该移动b,移动后为bacdefaccb,再来看a的情况,显然,移动次数变为2了,所以不影响结果。


参考代码:

while True:

    try:

        a=int(input())

        b=input().strip()

        b_temp=set(b)

        suc=True

        count=0

        index=0

        ans=0

        for i in b_temp:

            c=b.count(i)

            if a%2==0 and c%2==1:

                suc=False

                break

            if a%2==1 and c%2==1:

                count+=1

                

                if count>1:

                    suc=False

                    break

        if suc:

            for i in range(a//2):

                for j in range(a-1-i,i,-1):

                    if b[i]==b[j]:

                        string1=b[0:j]

                        string2=b[j]

                        string3=b[j+1:a-i]

                        string4=b[a-i:a]

                        ans+=len(string3)

                        b = string1 + string3 + string2 + string4

                        break

                    if b[a-i-1]==b[a-j-1]:

                        string1=b[0:i]

                        string2=b[i:a-j-1]

                        string3=b[a-j-1]

                        string4=b[a-j:a]

                        ans+=len(string2)

                        b = string1 + string3 + string2 + string4

                        break

            print(ans)

        else:

            print('Impossible')

    except:

        break


 

0.0分

2 人评分

  评论区

  • «
  • »