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).

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.

A linguagem C não nos providencia uma implementação de conjuntos interessante. Neste caso, tivemos que usar vetores, mas continuo usando a segunda equação normalmente, o raciocínio é o mesmo.

#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