Cubos coloridos - Huxley 632

Link do problema: https://www.thehuxley.com/problem/632

Nesse problema temos um desafio principal: "identificar quando dois cubos são iguais"

Para isso, vamos ter certeza que estamos entendendo o problema corretamente. Suponha o cubo abaixo:

1

2 4 5 3

6

Essa seria a representação do dado a seguir:

Escolhi representar esse dado como um array. As posições do array pouco importam, desde que você seja consistente. Ou seja, represente todos os cubos sempre com o padrão que você escolher.

No meu caso, fiz assim:

struct cubo{
    int faces[7];
};

Eu uso os índices de 1 a 6, ignorando o índice 0. Com a entrada do cubo acima, o meu array ficará assim:

[-1, 1, 2, 6, 4, 5, 3]

Ou seja, meu scanf é assim:

scanf("%d%d%d%d%d%d",&c.faces[1],&c.faces[2],&c.faces[4],&c.faces[5],&c.faces[6],&c.faces[3]);

Pronto. Agora precisamos identificar quando dois cubos são iguais.

Se eles estiverem exatamente na mesma posição, ou seja, se todas as suas fazes estiverem nas mesmas posições, então os dois arrays serão iguais. Esse é o caso mais fácil. Entretanto, pode ser que as faces estejam posicionadas de forma diferente. Nesse caso os arrays serão diferentes, mas ainda assim os cubos serão iguais.

Então, pode tentar o seguinte. Você deixa um cubo parado, rotaciona o segundo cubo e então compara os dois. Se eles forem iguais, você vai conseguir encontrar uma combinação de rotações que deixe ambos na mesma configuração das faces.

Porém, como vamos rotacionar um cubo. Olhe para o dado acima, como podemos rotacioná-lo?

Só existem 3 formas: horizontal, vertical ou no próprio eixo.

Veja o vídeo a seguir para visualizar essas 3 formas:

Perceba também que cada uma das formas, depois que você faz o movimento pela quarta vez, ele volta para a posição original. Por exemplo, pegue um dado, coloque sobre a mesa e gire 4 vezes para a esquerda. Pronto, ele voltou para a posição original.

E quantas possibilidades existem de girar o cubo? Ora, se são 3 tipos de rotação, cada uma delas depois de 4 movimentos ele volta pra posição original, então temos 4 X 4 X 4 possibilidades, ou seja, 64 possibilidades de girar o cubo.

funcao comparar_cubos(a, b)
    repita i de 1 a 4   
        repita k de 1 a 4
            repita j de 1 a 4
                compare o array a com o array b
                gire b no eixo
            fim_repita
            gire b na vertical
        fim_repita
        gire na horizontal
    fim_repita
fim_funcao

Finalmente precisamos contar quantos tipos existem. Nesse caso, eu guardei cada cubo em um vector:

vector<cubo> cubos;

Então eu comparo o primeiro cubo com todos os outros. Cada vez que eu acho um cubo igual, eu removo ele do array (removo inclusive o primeiro cubo que eu comparei com os demais).

Então pego o que restou da lista e mais uma vez pego o primeiro elemento e comparo com os demais, removendo todos que eu encontrar.

Pronto, o número de vezes que conseguirmos repetir esse procedimento até que a lista fique vazia, será exatamente a quantidade de tipos diferentes de cubos que existem.

:-)

Divirta-se!!!