bandera tricolor de pitón

Descripción del problema

        Supongamos que hay una cuerda con banderas rojas, blancas y azules. Al principio los colores de las banderas en la cuerda no estaban en orden, ahora necesitamos clasificar las banderas y ordenarlas en azul, blanco y rojo. Cabe destacar que solo puedes moverte sobre esta cuerda, y solo puedes cambiar dos banderas a la vez. Cómo mover las banderas en la menor cantidad de veces.

        La esencia de este problema es que hay tres tipos de elementos distribuidos aleatoriamente en una lista. El número de elementos es desconocido pero limitado. Necesitamos diseñar un programa para intercambiar las posiciones de estos elementos para que los elementos de esta lista se conviertan en tres. partes, cada parte Todas tienen los mismos elementos. Solo se pueden intercambiar las posiciones de dos elementos cada vez y se genera el paso de operación con el menor número de intercambios.

        Intercambiar las posiciones de dos elementos en una lista es fácil, pero lo difícil es hacerlo en un número mínimo de pasos. Hay que analizar cómo operar con el menor número de pasos. Primero, conocemos el número total de banderas, el número de cada tipo de bandera y el orden de disposición final de las banderas. Supongamos que hay 4 banderas rojas, blancas y azules cada una, y el orden de disposición final es azul, blanco. , Y Rojo.

Piense en cómo podemos operar para minimizar los pasos del intercambio. Debemos juzgar si el orden de ciertas banderas debe intercambiarse en función del orden final. Por ejemplo, la tercera bandera azul, la décima bandera roja y la undécima bandera roja no necesitan ser intercambiados Intercambiar lugares. En segundo lugar, al intercambiar banderas, primero debemos intercambiar la bandera que se va a intercambiar hasta su rango final, por ejemplo, la segunda bandera blanca se intercambia con la quinta bandera azul, la cuarta bandera blanca se intercambia con la sexta bandera azul, la séptima bandera roja La bandera se intercambia con El noveno intercambio de bandera blanca puede cambiarlas a sus respectivos rangos finales. Finalmente, intercambiamos las banderas restantes que deben intercambiarse para minimizar los pasos de la operación.

Por lo tanto, podemos dividir los pasos del intercambio en dos categorías, la primera categoría es el intercambio recíproco y la segunda categoría es el intercambio natural. Realizar primero intercambios recíprocos, seguidos de intercambios naturales, minimiza el número de pasos de intercambio.

programa de intercambio de diseño

        Con base en la descripción anterior, podemos dividir el programa de intercambio en dos partes, la primera parte es intercambio recíproco y la segunda parte es intercambio natural.

intercambio recíproco

        Durante el intercambio recíproco, primero debemos determinar el intervalo donde se ubican las banderas de cada color, y luego determinar si es necesario un intercambio en función del intervalo de las piezas de ajedrez, y al intercambiar, ambas banderas deben colocarse en sus respectivas posiciones finales. intervalos. Si las piezas de ajedrez no pueden satisfacer el intercambio recíproco, no se intercambiarán, dejándose al intercambio natural.

flag = ["红", "白", "蓝", "白", "蓝", "蓝", "红", "蓝", "白", "红", "红", "白"]  # 排序旗子
order = ["蓝", "白", "红"]  # 最终顺序

# 互惠交换代码
range_list = [0]  # 定义各色棋子区间列表
for i in order:
    range_list.append(flag.count(i))  # 先统计各色棋子的数量
for i in range(len(range_list)):
    if i > 0:
        range_list[i] = range_list[i - 1] + range_list[i]  # 算出各色棋子在绳子上的区间
for i in range(len(order)):
    for n in range(range_list[i], range_list[i + 1]):  # 按最终的棋子顺序输出棋子的区间
        if flag[n] != order[i]:  # 判断棋子是否属于此段区间
            index = order.index(flag[n])  # 找出该棋子在颜色排布列表中的索引
            if order[i] in flag[range_list[index]:range_list[index + 1]]:  # 判断该区间颜色的棋子是否存在于可直接交换区间中
                for m in range(range_list[index], range_list[index + 1]):  # 逐个输出直接交换区间的棋子
                    if flag[m] == order[i]:  # 判断棋子是否为直接交换的棋子
                        flag[n], flag[m] = flag[m], flag[n]  # 交换棋子
                        print(f'{n + 1} 旗和 {m + 1} 旗交换位置')  # 打印交换位置
                        print(flag)  # 打印交换后的棋子顺序
                        break  # 结束循环

intercambio natural

        Durante el intercambio natural, debe verificar si hay indicadores que no hayan regresado al intervalo final. Si los hay, intercambiaremos los indicadores que pertenecen a este intervalo fuera del intervalo a este intervalo. No se requiere procesamiento ni pensamiento, Es un simple intercambio.

for i in range(len(order)):
    for n in range(range_list[i], range_list[i + 1]):  # 按最终的棋子顺序输出棋子的区间
        if flag[n] != order[i]:  # 判断棋子是否属于此段区间
            for x in range(range_list[i + 1], range_list[-1]):  # 循环输出该区间以外的棋子
                if flag[x] == order[i]:  # 判断棋子是否为该区间的棋子
                    flag[n], flag[x] = flag[x], flag[n]  # 交换棋子
                    print(f'{n + 1} 旗和 {x + 1} 旗交换位置')  # 打印交换位置
                    print(flag)  # 打印交换后的棋子顺序
                    break  # 结束循环

código completo

        Combinando el intercambio recíproco con el intercambio natural, el intercambio recíproco viene primero y el intercambio natural termina. Podemos obtener un programa de intercambio con la menor cantidad de pasos, el código completo es el siguiente:

flag_list = ["红", "白", "蓝", "白", "蓝", "蓝", "红", "蓝", "白", "红", "红", "白"]
order_list = ["蓝", "白", "红"]


def three_flag(flag, order):
    """
    三色旗问题

    :param flag: 旗子列表
    :param order: 颜色排布列表
    :return:
    """
    range_list = [0]
    for i in order:
        range_list.append(flag.count(i))
    for i in range(len(range_list)):
        if i > 0:
            range_list[i] = range_list[i - 1] + range_list[i]
    for i in range(len(order)):
        for n in range(range_list[i], range_list[i + 1]):
            if flag[n] != order[i]:
                index = order.index(flag[n])
                if order[i] in flag[range_list[index]:range_list[index + 1]]:
                    for m in range(range_list[index], range_list[index + 1]):
                        if flag[m] == order[i]:
                            flag[n], flag[m] = flag[m], flag[n]
                            print(f'{n + 1} 旗和 {m + 1} 旗交换位置')
                            print(flag)
                            break
    for i in range(len(order)):
        for n in range(range_list[i], range_list[i + 1]):
            if flag[n] != order[i]:
                for x in range(range_list[i + 1], range_list[-1]):
                    if flag[x] == order[i]:
                        flag[n], flag[x] = flag[x], flag[n]
                        print(f'{n + 1} 旗和 {x + 1} 旗交换位置')
                        print(flag)
                        break


three_flag(flag_list, order_list)

Los resultados de la ejecución son los siguientes:

Con esta función se pueden usar banderas de 3 colores, banderas de 4 colores, banderas de 5 colores, sin importar cuantos colores tengan las banderas. Siempre que pasemos la lista de banderas a ordenar y el orden final, podemos obtener los pasos mínimos de intercambio para ordenar las banderas.

Supongo que te gusta

Origin blog.csdn.net/qq_40148262/article/details/130990578
Recomendado
Clasificación