1 条题解

  • 0
    @ 2026-9-30 12:57:32

    C++ :

    
    #include <cstdio>
    #include <cstring>
    /* 最少相邻交换变成回文串。
       可行性:奇数个数的字符种数 <= (n 为奇数 ? 1 : 0)。
       贪心:从两端向中间配对;为左端字符 s[i] 找最靠右的相同字符 k。
         · 找到 -> 把它一路交换到右端(记 k..j 的交换数),配对消去;
         · 没找到 -> s[i] 就是唯一的落单字符,只能往中间挪(代价 n/2 - i),
                    且只允许出现一次(n 为奇数时)。 */
    static char a[8005];
    int main(){
        int n;
        if(scanf("%d", &n) != 1) return 0;
        scanf("%s", a);
        int cnt[26] = {0};
        for(int i = 0; i < n; i++) cnt[a[i] - 'a']++;
        int odd = 0;
        for(int i = 0; i < 26; i++) odd += cnt[i] & 1;
        if(odd > (n & 1)){ printf("Impossible\n"); return 0; }
        int i = 0, j = n - 1;
        long long moves = 0;
        bool used = false;
        while(i < j){
            int k = j;
            while(k > i && a[k] != a[i]) k--;
            if(k == i){
                if((n % 2 == 0) || used){ printf("Impossible\n"); return 0; }
                used = true;
                moves += n / 2 - i;
            } else {
                for(int t = k; t < j; t++){ char c = a[t]; a[t] = a[t+1]; a[t+1] = c; moves++; }
                j--;
            }
            i++;
        }
        printf("%lld\n", moves);
        return 0;
    }
    
    
    • 1

    信息

    ID
    2822
    时间
    1000ms
    内存
    256MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者