[PTA] 7-2 Encuentra el número de pares invertidos (30 puntos)

7-2 Encuentra el número de pares inversos (30 puntos)

Nota: Se requiere que la complejidad de tiempo del algoritmo para este problema sea O (nlogn); de lo contrario, la puntuación no es válida

题目来源:http://poj.org/problem?id=1804
Antecedentes Raymond Babbitt vuelve loco a su hermano Charlie. Recientemente, Raymond contó 246 palillos de dientes esparcidos por todo el piso en un instante con solo mirarlos. E incluso puede contar cartas de póquer. A Charlie también le encantaría poder hacer cosas geniales como esa. Quiere vencer a su hermano en una tarea similar.
Problema Esto es lo que piensa Charlie. Imagina que obtienes una secuencia de N números. El objetivo es mover los números para que al final se ordene la secuencia. La única operación permitida es intercambiar dos números adyacentes. Probemos con un ejemplo: Comience con: 2 8 0 3 intercambio (2 8) 8 2 0 3 intercambio (2 0) 8 0 2 3 intercambio (2 3) 8 0 3 2 intercambio (8 0) 0 8 3 2 intercambio (8 3) 0 3 8 2 intercambiar (8 2) 0 3 2 8 intercambiar (3 2) 0 2 3 8 intercambiar (3 8) 0 2 8 3 intercambiar (8 3) 0 2 3 8

Traducción:
Esta es idea de Charlie. Suponga que obtiene una secuencia con N números. Su objetivo es mover los números para que la secuencia esté en orden al final. La única operación permitida es intercambiar dos números adyacentes. Probemos un ejemplo:
primero: 2 8 0 3 swap(2 8)
8 2 0 3 swap(2 0) 8
0 2 3 swap(2 3)
8 0 3 2 swap(8 0)
0 8 3 2 swap(8 3)
0 3 8 2 intercambiar (8 2)
0 3 2 8 intercambiar (3 2)
0 2 3 8 intercambiar (3 8)
0 2 8 3 intercambiar (3 8)
finalmente obtener 0 2 3 8

Entonces, la secuencia (2 8 0 3) se puede ordenar con nueve intercambios de números adyacentes. Sin embargo, incluso es posible clasificarlo con tres intercambios de este tipo: Comience con: 2 8 0 3 intercambio (8 0) 2 0 8 3 intercambio (2 0) 0 2 8 3 intercambio (8 3) 0 2 3 8 La
pregunta es: ¿Cuál es el número mínimo de intercambios de números adyacentes para ordenar una secuencia dada? Dado que Charlie no tiene las capacidades mentales de Raymond, decide hacer trampa. Aquí es donde entras en juego. Él le pide que escriba un programa de computadora para él que responda la pregunta en O (nlogn). Ten por seguro que pagará un muy buen premio por ello.

Traducción:
Entonces, la secuencia (2 8 0 3) se puede ordenar intercambiando 9 números adyacentes. Sin embargo, incluso se puede ordenar con tres intercambios de este tipo:
inicio: 2 8 0 3 intercambio (8 0)
2 0 8 3 intercambio (2 0)
0 2 8 3 intercambio (8 3)
obtiene 0 2 3 8

Formato de entrada:

La primera línea contiene la longitud N (1 <= N <= 1000) de la secuencia; la segunda línea contiene los N elementos de la secuencia (cada elemento es un número entero en [-1000000, 1000000]). Todos los números en esta línea están separados por espacios en blanco.

Traducción: la primera línea contiene la longitud N de la secuencia (1 <= N <= 1000); la
segunda línea contiene los N elementos de la secuencia (cada elemento es un número entero de [-1000000, 1000000]).
Todos los números en esta línea están separados por un solo espacio

Formato de salida:

Imprima una sola línea que contenga el número mínimo de intercambios de números adyacentes necesarios para ordenar la secuencia dada.

Traducción: Imprime el número mínimo de intercambios de dígitos adyacentes requeridos para ordenar la secuencia dada

Muestra de entrada:

Aquí se proporciona un conjunto de entradas. Por ejemplo:

6
-42 23 6 28 -100 65537
Sin línea en blanco al final

Salida de muestra:

La salida correspondiente se da aquí. Por ejemplo:

5 sin línea en blanco al final

Ideas:

1. Debido a que el requisito de complejidad es O(nlogn), se adopta el método de clasificación por fusión .
2. El título del tema es un par inverso, y el par inverso es <a[i], a[j]> , donde i<j, pero a[i]>a[j]
3. El primer paso es usar mergesort() para dividir la matriz en Las dos mitades se ordenan y se llaman recursivamente.
El segundo paso usa merge() para volver a unir las matrices separadas.
4. En merge(), la matriz completa a se divide en dos mitades, y el tamaño se compara desde el primer número de las dos mitades, es decir, a[i] y a[j], y la matriz más pequeña se coloca en matriz b. Además, si hay un número mayor que a[j] a la izquierda de a[j] (y no entra en la matriz b), significa que se puede formar un par inverso , y el número de tales números se registra como núm.
5. La función principal emite num.

#include<iostream>
using namespace std;
int num;//逆序对个数
int a[10005],b[10005];

int merge(int a[],int b[],int l,int m,int r){
    
    
    int i=l,j=m+1,k=l;//k:数组b的下标
    //将2803分成两个数组(且两数组已经分别排好序),前面一半28,后面一半03,从两个数组的第一个数字开始比较,所以i=l,j=m+1
    while((i<=m)&&(j<=r)){
    
    
        if(a[i] <= a[j]){
    
    
            b[k++]=a[i++];//左右比较,将较小的数字放入数组b
        }else{
    
    
            b[k++]=a[j++];
            num+=m+1-i;//num表示在a[j]左边的数字中(除了已经进入b数组的数字),有多少个数字可以和a[j]组成逆序对(即比a[j]大)
        }
    }
    if(i>m){
    
    //将右边剩下的都填入b
        for(int q=j;q<=r;q++){
    
    
            b[k++]=a[q];
        }
    }else{
    
    //将左边剩下的都填入b
        for(int q=i;q<=i;q++){
    
    
            b[k++]=a[q];
        }
    }
    for(int q=l;q<=r;q++){
    
    //复制回a数组
        a[q]=b[q];    }
}

int mergesort(int a[],int l,int r){
    
    
    if(r>l){
    
    
        int m=(r+l)/2;
        mergesort(a,l,m);
        mergesort(a,m+1,r);
        merge(a,b,l,m,r);
    }
}

int main(){
    
    
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
    
    
        cin>>a[i];
    }
    mergesort(a,0,n-1);
    cout<<num;
}

Supongo que te gusta

Origin blog.csdn.net/qq_51669241/article/details/120469588
Recomendado
Clasificación