Borrado de números Gym-102452E (prefijo y)

Después de una larga conferencia de estadística, los estudiantes están a punto de salir del aula cuando de repente comienza a llover con fuerza. Como no tienes tu paraguas contigo, decides quedarte en el aula y esperar que la lluvia termine pronto. Varios minutos después, eres la única persona que queda en el salón de clases. Te das cuenta de algo interesante: hay N (N es impar) números enteros distintos escritos en una línea en la pizarra. Como estás muy aburrido, decides borrar esos números de la pizarra para que el conserje tenga menos trabajo que hacer.

Pedazo de tiza y pizarra. Dominio publico.
Como acaba de aprender los conceptos de mediana durante la conferencia, inventó la siguiente operación de borrado para tres números enteros: borre el número más grande y el número más pequeño de la pizarra, de modo que solo quede la mediana de los tres números. Decide repetir el siguiente proceso: elija tres enteros consecutivos en la pizarra y aplique la operación de borrado en ellos. Después de esta operación, el número de enteros en la pizarra disminuirá en 2. Finalmente, solo quedará un entero después de que este proceso se repita N-12 veces. De repente, se te ocurre una pregunta interesante: ¿qué enteros pueden sobrevivir hasta el final?

Entrada
La entrada contiene varios casos. La primera línea de la entrada contiene un solo entero T (1≤T≤1000), el número de casos.

Para cada caso, la primera línea de la entrada contiene un único entero N (1≤N≤5000, N es impar), el número de enteros en la pizarra inicialmente. La segunda línea contiene N números enteros distintos a1, a2,…, aN (1≤ai≤N), donde ai (1≤i≤n) denota el i-ésimo entero en la pizarra.

Se garantiza que la suma de N en todos los casos no exceda de 104.

Salida
Para cada caso, imprima una cadena que consta de N caracteres en una sola línea. El carácter i-ésimo (1≤i≤N) de la cadena debe ser '1' si es posible que ai permanezca como el único entero al final; de lo contrario, debe ser '0'.

Ejemplo
de entrada
2
5
3 1 2 5 4
3
2 3 1
de salida
10001
100

Hay una pregunta 1e6 sobre la escuela de Niukeduo, puedes ir y estudiarla: Portal .

Pregunta:
Puede seleccionar 3 números consecutivos cada vez y eliminar los valores máximo y mínimo. Queda un número en la secuencia final.
Vea si se puede dejar cada número.

Idea:
El rango de datos de 5000 se puede pensar en n 2 n ^ 2norte2 .
Luego, recorra cada número X, y luego establezca todos los números mayores que este número en 1, y los números menores que este número en 0.

Luego asegúrese de que el número de 0 y 1 sea igual y, finalmente, se puede garantizar que el número permanezca. Dado que el número de 0 y 1 es igual, se debe encontrar un par de 0 y 1 adyacentes (o 0 X 1) cada vez. Después de la eliminación, el número de 0 y 1 se reduce en 1, y finalmente se reducen todos 0 y 1.

Entonces, nuestra pregunta es si podemos igualar el número de 0 y 1 mediante la operación. Si hay más 0, disminuirá en 0, y si hay más 1, disminuirá en 1.


En primer lugar, si hay una X en los 3 números, solo puede tener la forma de 0 X 1 o 1 X 0, por lo que el tamaño relativo de los números 0 y 1 no se puede cambiar.
Entonces, los números de la izquierda y la derecha de X se consideran por separado.

Para 000 y 111, es obvio que se pueden reducir 2 0 o 2 1, lo que puede cambiar la relación de tamaño relativo. Pero además de esto, secuencias como 00100 y 11011 también pueden desempeñar este papel. ¿Cómo saber qué secuencias pueden reducir 0 o reducir 1?


La respuesta es:
siempre que el número de ceros en esta secuencia sea mayor o igual al número de unos, entonces 2 ceros se pueden reducir relativamente.

Debido a que el número de ceros en esta secuencia es mayor o igual al número de unos, de acuerdo con la conclusión anterior, cada vez que busque 01 o 10 adyacentes, puede reducir el número de ceros y el número de unos al mismo tiempo, y el último restante es 000 .


Por lo tanto, luego de enumerar cada número, se obtiene el número de 0 y el número de 1. Si hay más 0, se reducirá en 0. Luego, incluso si se encuentra la suma del prefijo, aumentará en uno, y cuando encuentre 1, se restará en uno. Si la suma del prefijo es negativa, se borrará. Si es mayor o igual a 3, el número de ceros se reduce en 2. De esta forma se reduce el número de ceros. Lo mismo para 1

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long ll;

const int maxn = 5e3 + 7;
int vis[maxn],a[maxn];
int n;

bool check(int pos) {
    
    
    int zero = 0,one = 0;
    for(int i = 1;i <= n;i++) {
    
    
        if(a[i] == a[pos]) vis[i] = -1;
        else if(a[i] > a[pos]) {
    
    
            vis[i] = 1;
            one++;
        }
        else {
    
    
            vis[i] = 0;
            zero++;
        }
    }
    
    if(one == zero) return true;
    
    int ONE = one,ZERO = zero;
    int sum = 0;
    if(zero > one) {
    
    
        for(int i = 1;i <= pos - 1;i++) {
    
    
            if(zero == one) return true;
            if(vis[i] == 0) {
    
    
                sum++;
            } else if(vis[i] == 1) {
    
    
                sum--;
            }
            if(sum < 0) sum = 0;
            if(sum == 3) {
    
    
                zero -= 2;
                sum = 1;
            }
        }
        sum = 0;
        for(int i = pos + 1;i <= n;i++) {
    
    
            if(zero == one) return true;
            if(vis[i] == 0) {
    
    
                sum++;
            } else if(vis[i] == 1) {
    
    
                sum--;
            }
            if(sum < 0) sum = 0;
            if(sum == 3) {
    
    
                zero -= 2;
                sum = 1;
            }
        }
    } else {
    
    
        for(int i = 1;i <= pos - 1;i++) {
    
    
            if(zero == one) return true;
            if(vis[i] == 0) {
    
    
                sum--;
            } else if(vis[i] == 1) {
    
    
                sum++;
            }
            if(sum < 0) sum = 0;
            if(sum == 3) {
    
    
                one -= 2;
                sum = 1;
            }
        }
        sum = 0;
        for(int i = pos + 1;i <= n;i++) {
    
    
            if(zero == one) return true;
            if(vis[i] == 0) {
    
    
                sum--;
            } else if(vis[i] == 1) {
    
    
                sum++;
            }
            if(sum < 0) sum = 0;
            else if(sum == 3) {
    
    
                one -= 2;
                sum = 1;
            }
        }
    }
    return one == zero;
}

int main() {
    
    
    int T;scanf("%d",&T);
    int kase = T;
    int cnt = 0;
    while(T--) {
    
    
        scanf("%d",&n);
        cnt++;
        for(int i = 1;i <= n;i++) {
    
    
            scanf("%d",&a[i]);
        }

        for(int i = 1;i <= n;i++) {
    
    
            if(check(i)) {
    
    
                printf("1");
            } else {
    
    
                printf("0");
            }
        }
        printf("\n");
    }
    return 0;
}
//0111

Supongo que te gusta

Origin blog.csdn.net/tomjobs/article/details/108993931
Recomendado
Clasificación