蓝桥杯试题 基础练习 完美的代价 Python and c++

试题 基础练习 完美的代价

提交此题  

资源限制

时间限制:1.0s   内存限制:512.0MB

问题描述

  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)

输入格式

  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母

输出格式

  如果可能,输出最少的交换次数。
  否则输出Impossible

样例输入

5
mamad

样例输出

3

Python版

注意:下面有两种写法,有一种速度稍微。

速度快一点的是

n = int(input())
s = list(input())


def to_solve(s, n):
    j = n - 1
    cnt = 0   # cnt用来统计交换的次数
    flag = 0  # flag判断是否已经有一个单独的奇个数的字符了
    i = 0
    while i < j:
        # i指针从头遍历到倒数第二个字符
        # k指针从后面往前一直到i寻找和s[i]相同的s[k]
        for k in range(j, i - 1, -1):
            if k == i:  # 如果找不到相同的
                if n % 2 == 0 or flag == 1:
                    print("Impossible")
                    return None
                flag = 1
                cnt += n // 2 - i
            elif s[k] == s[i]:
                for l in range(k, j):
                    s[l], s[l + 1] = s[l + 1], s[l]  # 把s[k]换到s[j]处
                    cnt += 1  # 统计交换次数
                j -= 1
                break
        i += 1
    return cnt


s = to_solve(s, n)
if s is not None:
    print(s)

下面是速度稍微慢点的,有时候机器运行速度慢会超时

n = int(input())
s = list(input())


def to_solve(s, n):
    j = n - 1
    cnt = 0   # cnt用来统计交换的次数
    flag = 0  # flag判断是否已经有一个单独的奇个数的字符了
    i = 0
    while i < j:  # i指针从头遍历到倒数第二个字符
        k = j  # k指针从后面往前一直到i寻找和s[i]相同的s[k]
        while k >= i:
            if k == i:  # 如果找不到相同的
                if n % 2 == 0 or flag == 1:
                    return "Impossible"
                flag = 1
                cnt += n // 2 - i  # //取整数部分
            elif s[k] == s[i]:
                for l in range(k, j):
                    s[l], s[l + 1] = s[l + 1], s[l]  # 把s[k]换到s[j]处
                    cnt += 1  # 统计交换次数
                j -= 1
                break
            k -= 1
        i += 1
    return cnt


print(to_solve(s, n))

c++版

#include <iostream>
using namespace std;
int main() {
    int n;
    cin >> n;
    string s;
    cin >> s;
    int j = n - 1;
    int cnt = 0;//cnt用来统计交换的次数
    int flag = 0;//flag判断是否已经有一个单独的奇个数的字符了
    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的两种情况
                    cout << "Impossible";
                    return 0;
                }
                flag = 1;
                cnt += n / 2 - i;
            } else if(s[k] == s[i]) {
                for(int l = k; l < j; l++) {
                    swap(s[l], s[l+1]);//把s[k]换到s[j]处
                    cnt++;//统计交换次数
                }
                j--;
                break;
            }
        }
    }
    cout << cnt;
    return 0;
}
发布了67 篇原创文章 · 获赞 22 · 访问量 7145

猜你喜欢

转载自blog.csdn.net/weixin_43906799/article/details/104896237