Problema digital extraño con proceso de prueba

tema

Inserte la descripción de la imagen aquí

análisis

Primero, convierta la matriz bidimensional en una matriz unidimensional.
Primero, si 0 se mueve en la fila, es fácil demostrar que esto no cambiará el orden inverso de la secuencia excepto 0.
Si 0 se mueve en la columna, no cambia la división de 0. Para el orden inverso de la secuencia externa, la demostración se da a continuación:

1. Dado que las filas y columnas de la matriz cuadrada dada son todas números impares, debe haber un número par entre
los dos números en la misma columna después de que se transforman en una dimensión. 2. Suponiendo que los dos números en la misma columna a operar son ayb, en el intervalo [a, b], hay x números mayores que byy números menores que b.
3. Si b va a la posición de a, entonces b reducirá y orden inverso y aumentar x orden inverso. Esto hará que el cambio del par de orden inverso sea xy
4. Dado que la pregunta muestra que no hay elementos repetidos en toda la matriz cuadrada, el número en el intervalo [a, b] es mayor que y o menor que y, por lo que x + y es un número par, por lo que xey son pares o impares, por lo que xy debe ser un número par
5. La operación dada en la pregunta debe operar en 0, por lo que a = 0 en el intervalo [a, b] y en el intervalo Todos los números son mayores que 0, por lo que el cambio al orden inverso de la operación 0 debe ser la longitud del intervalo, la longitud del intervalo debe ser un número par
6, y la operación de 0 debe ser reversible, por lo que [0, b] y [b, 0] son ​​pares Los cambios en el orden inverso son opuestos entre sí, por lo que la paridad permanece sin cambios.
7. En resumen, mover 0 en el la columna no cambia el número inverso

Por lo tanto, la respuesta se puede obtener buscando el orden inverso: si la paridad de orden inverso es la misma, es alcanzable, de lo contrario no es alcanzable.

Los blogs que vi finalmente demostraron este paso, pero creo que este tipo de proceso de prueba es un poco autoengañoso, porque no hay un argumento claro de por qué las matrices cuadradas con la misma paridad son mutuamente alcanzables.

Aquí trato de dar esta prueba:
escribe la conclusión primero:Las matrices cuadradas con la misma paridad son mutuamente alcanzables, y las matrices cuadradas con diferentes paridades no son mutuamente alcanzables.
Aquí escribí por primera vez un programa de búsqueda violento, ¡y los resultados fueron muy lentos! ¡Y la cantidad de datos no puede ser demasiado grande! El resultado final es de hecho la conclusión anterior. Si está interesado, puede escribir una y probarla usted mismo. ¡
Regrese al tema! ¡probar! ¡No rocíe si no le gusta!

1. Después de convertir la matriz bidimensional en una matriz unidimensional, puede mover cualquier número a la última posición a través de las dos operaciones dadas en el título.
2. Luego, movemos el número más grande a la última posición, el segundo más grande Mueva el número a la penúltima posición, y así sucesivamente
3. Para cualquier secuencia que recurramos de esta manera, inevitablemente obtendremos uno de dos resultados. El primer tipo: 0 1 2…, el primer tipo 0 2
1…, corresponden respectivamente a dos matrices cuadradas con diferentes paridades, y esta forma final no se puede transformar entre sí 4, por lo que las matrices cuadradas con la misma paridad son mutuamente excluyentes. , las matrices cuadradas con diferentes paridades son mutuamente inalcanzables

Código

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 500*500+10;
int n;
int tr[N];
int lowbit(int x)
{
    
    
    return x & -x;
}
void add(int x, int c)
{
    
    
    for (int i = x; i <= n; i += lowbit(i))
        tr[i] += c;
}
int sum(int x)
{
    
    
    int res = 0;
    for (int i = x; i; i -= lowbit(i))
        res += tr[i];
    return res;
}
int main()
{
    
    
    while(cin>>n)
    {
    
    
        n=n*n;
        memset(tr,0,sizeof(tr));
        ll res1=0;
        for(int i=1;i<=n;i++)
        {
    
    
            int x;
            scanf("%d",&x);
            if(x)
            {
    
    
                res1+=sum(n-1)-sum(x);
                add(x,1);
            }
        }
        memset(tr,0,sizeof(tr));
        ll res2=0;
        for(int i=1;i<=n;i++)
        {
    
    
            int x;
            scanf("%d",&x);
            if(x)
            {
    
    
                res2+=sum(n-1)-sum(x);
                add(x,1);
            }
        }
        if((res1%2)==(res2%2)) cout<<"TAK"<<endl;
        else cout<<"NIE"<<endl;
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_46126537/article/details/112860675
Recomendado
Clasificación