踏乡墨客


私信TA

用户名:njuptxll

访问量:1814

签 名:

njuptxll

等  级
排  名 23617
经  验 631
参赛次数 0
文章发表 3
年  龄 0
在职情况 学生
学  校 南邮
专  业 通信工程

  自我简介:

解题思路:

     1.impossible的情况:如果有一个字符出现的次数是奇数次数,而且n是偶数,那么不可能构成回文
       如果n是奇数,但是已经有一个字符出现的次数是奇数次数了,那么如果又有一个字符是奇数次数,
 就不可能构成回文。

     2.如果n是奇数,计算中间那个字符交换的次数的时候,不需要模拟把这个数移动到中间去,因为移动到中 间的话假设有一对数都在左边或者都         在右边,那么交换成回文的时候就要经过中间,就会每次把cnt多加了1,而这个1是没有必要的,因为可以所有的回文移动完了之后再把这个           独立的奇数移动过去,才能保证交换次数最少。

    3.参见大牛的博客https://blog.csdn.net/liuchuo/article/details/51990430

注意事项:

    注意分类n为奇数和偶数吧   

参考代码:

#include <iostream>
#include <cstdio>
using namespace std;
int main() {
   int n;
   scanf("%d",&n);
   char a[10000];
   scanf("%s",a);
   int j=n-1;//j指向字符串需要交换的末尾下标
   int count=0;//记录交换次数
   int flag=0;//记录是否有字符只出现了单次,
                // 未找到相同字符串时为1
    for (int i = 0; i < j ; i++) {//i指针从头遍历到倒数第二个字符
        for (int k = j; k >=i ; k--) {//k指针从后面往前一直到i寻找和s[i]相同的s[k]
            if(k==i){//如果找不到相同的
                if(n%2==0||flag==1){//impossible的两种情况
                    printf("Impossible");
                    return 0;
                }
                flag=1;
                count+=(n-1)/2-i;  //移动到中间需要的交换次数(距离即为交换次数),
                                    // (不需要现在交换过去,最后交换)
                                    // 此时n一定为奇数,因为n是偶数已经直接输出Impossible了
            }
            else{
                if(a[k]==a[i]){
                    for(int l=k;l<j;l++){
                        swap(a[l],a[l+1]);//把s[k]换到s[j]处
                        count++;//统计交换次数
                    }
                    j--;
                    break;
                }
            }

        }
    }
    printf("%d",count);
    return 0;
}


 

0.0分

3 人评分

  评论区

  • «
  • »