1104 - Troca de Cartas

Vamos rever teoria de conjuntos!

Descrição

Solução

O objetivo deste problema é descobrir qual é a maior quantidade de pares de cartas que as meninas podem trocar entre si, considerando que nenhuma das duas gostaria de receber uma carta repetida. Uma boa maneira de conseguir este resultado é executando os seguintes passos:

  1. Tirar todas as cartas repetidas entre si do baralho das duas meninas

  2. Tirar todas as cartas que aparecem tanto num baralho quanto no outro

  3. Entre as cartas que sobrarem, selecionar a quantidade de cartas do menor baralho

Se lidarmos com conjuntos, onde os conjuntos A e B representam as cartas de Alice e Beatriz, respectivamente, o primeiro passo já será resolvido automaticamente, já que conjuntos não aceitam elementos repetidos. Desta maneira, agora podemos fazer a diferença entre os dois conjuntos e ficar com a menor entre elas para nossa resposta.

Podemos calcular a diferença diretamente ou usar uma das duas equações abaixo para calcular a cardinalidade da diferença para gente (que no final das contas, é o que interessa).

AB=ABAouAB=AAB|A - B| = |A \cup B| - |A| \\ \text{ou} \\ |A - B| = |A| - |A \cap B|

Em todas as implementações exibidas abaixo, usamos a segunda equação. O motivo de não calcular A - B e B - A direto é apenas a fim de economizar memória.

#include <string.h>
#include <stdio.h>

int main(){
    int alice[100001], beatriz[100001];
    int A, B, carta, so_alice, so_beatriz, ambas;

    while(scanf("%d %d", &A, &B)){
        if(!A && !B)    break;

        memset(alice, 0, sizeof(alice));
        memset(beatriz, 0, sizeof(beatriz));

        so_alice = 0;
        for(int i = 0; i < A; ++i){
            scanf("%d", &carta);

            if(!alice[carta]){
                alice[carta] = 1;
                ++so_alice;
            }
        }

        ambas = 0;
        so_beatriz = 0;
        for(int i = 0; i < B; ++i){
            scanf("%d", &carta);

            if(!beatriz[carta]){
                beatriz[carta] = 1;
                ++so_beatriz;
                if(alice[carta])    ++ambas;
            }
        }

        so_alice -= ambas;
        so_beatriz -= ambas;

        printf("%d\n", so_alice < so_beatriz ? so_alice : so_beatriz);
    }

    return 0;
}

Last updated

Was this helpful?