A resolução do problema com 2 canibais e 2 missionários é facílima: basta mandar primeiro os dois canibais. Envia-se um de volta e manda-se os 2 missionários. Traz-se um gajo qualquer de volta para pegar o canibal que resta e está feito.
Com 3 de cada faz-se da seguinte maneira:
1ª ida - manda-se dois canibais;
1ª volta - vem um canibal;
2ª ida - envia-se os 2 canibais que ficaram;
2ª volta - volta um dos canibais;
3ª ida - vão dois missonários;
3ª volta - volta um missonário e um canibal;
4ª ida - vao dois missionários;
4ª volta - volta um canibal;
5ª ida - vão dois canibais;
5ª volta - volta um canibal ou um missionário (tanto faz);
6ª ida - vao os dois restantes (podem ser um canibal e um missionário ou dois canibais, dependendo da escolha anterior) e está o jogo terminado.
Se não me engano, está certo.
Nota - Esta é uma das soluções possíveis; existem mais, mas não vou ficar aqui o dia todo a resolver esta charada de todas as formas possíveis e imaginárias.
Quanto à maneira de programar isto, eu não sei programar em C, mas deduzo que basta criar uma instrução
if em que o número de canibais nunca possa ser maior que o de missionários em situação nenhuma. Acho que é a maneira mais fácil de resolver o problema.
Cumprimentos e depois mostra-nos o trabalho
