Divisibilidade. Número contendo mais de 49 algarismos

Só pode ser utilizado tipos de dados primitivos, tais como int, double e boolean,
o tipo BigInteger, e listas encadeadas implementadas implementanda por mim.

Não é permitido o uso de qualquer tipo de vetor ou outra estrutura de alocação de memória. Também não é permitido simular
vetores por meio de String.

Considere uma lista L de tamanho n contendo dígitos. Abaixo, um exemplo de uma lista L1 de
tamanho 10: L1 = [4 3 9 1 3 0 2 8 3 3]
Considere agora a possibilidade de formar números múltiplos de um inteiro k a partir de arranjos dos dígitos presentes em L. Por exemplo, 980 é formado por dígitos da lista L1 e é múltiplo de k = 49. Abaixo, um conjunto de múltiplos de k = 4 que podem ser formados a partir de dígitos de L1: Múltiplos = {0, 4, 8, 12, 20, 24, 28, 32, 40, 48, 80, 84, 92,…}

Observe que os múltiplos 16, 36, 44, 52, dentre outros, não puderam ser formados. Isso acontece
porque a lista não contém os dígitos, ou a quantidade necessária de digítos, necessários para
formar o múltiplo. Nesse caso, a lista não possue o dígito 6, o que impossibilita a formação dos
múltiplos 16 e 36, o dígito 5, o que impossibilita a formação do múltiplo 52, e dois dígitos 4, o que
impossibilita a formação domúltiplo 44.
O objetivo deste trabalho é, a partir de uma lista L e umnúmero k, que serão dados como entrada,
encontrar o maior múltiplo de k usando somente os dígitos presentes em L.Se um dígito aparece na
lista somente uma vez, esse dígito só poderá ser usado uma única vez para formar omúltiplo. Se ele aparecer duas vezes, poderá ser usado somente duas vezes, e assim por diante.
Bom eu recebo como parametro uma String linha e implementei uma fila onde os valores lidos nessa linha são inserido em ordem decrescente. A linha conterá 49 dígitos. De modo que não posso encontrar já de cara o maior e tentar colocar em um int ou long por causa de nullexeption.
Preciso de alguma maneira de manipular os digitos (já em ordem decrecente) e fazer as verificações se esse numero é divisivel por K. - Lembrando que recebo uma lista encadeada (tanto faz se dupla ou simples) como parametro.

Por enquanto a idéia que tenho é que tera de ser um metodo recursivo.

Se alguém puder me ajudar eu agradeço muito.

E qual é a dúvida? Poderia mostrar algum código do que vc já fez?

Você vai ter que implementar o teu próprio BigInteger, mas sem usar qualquer coisa parecida com vetores, nem listas encadeadas?

A única forma que vejo como fazer isso é ter variáveis com nome long1, long2, long3… o que é bem estúpido… e fazer sua própria matemática de divisibilidade.

:?

Pra chegar na recursividade, que é a única ideia que vc tem, falta codificar alguma coisam, então mão na massa e sai programando! :wink:

Bom… andei pensando de um outro jeito onde faria da seguinte maneira:

essa é a String recebida: 6 3 5 7 1

A lista insere decrescente e fica assim minha lista

7 6 5 3 1

A pessoa digita um K, (exemplo 2)

jogarei esse n° 76531 em um BigInteger e verificarei se ele é divisível por (k)2
Como não é… eu decremento 1, até encontrar o primeiro que seja.
Logo fica assim: 76531 - 1 = 76530 --> Pego esse n° e verifico se é possĩvel forma-lo com os digitos que estão dentro da minha lista ( 7 6 5 3 1).
Se não… começo a decrementar de K em K (2 em 2)

76530 - 2 = 76528 (Faço a msma verificação enquanto não for possĩvel formar esse dígito com os algarismos que eu possuo na lista e enqaunto for diferente de zero)

uma hora eu vou chegar em 75316 que é divisível por 2.

A minha dúvida agora é… tem como eu pegar dígito por dígito de um BigInteger para poder contar a quantidade de cada algarismo e compara-lá à quantidade que eu tenho (e que consigo ver) da minha lista?

76531(int)
possue
Qnt - Algarismo
1 - 7,
1 - 6
1 - 5
1 - 3
1 - 1
Através da Lista consigo conta-los. Mas como faço para contar os dígitos de um bigInteger?
76531(BigInteger) ??? Como contar???

Desculpe se parece repetitivo, mas é pra poder ficar claro.

Isso parece um daqueles problemas do Google Code Jam, ou do TopCoder.

Para pegar dígito por dígito de um BigInteger, você pode convertê-lo para String, por exemplo, e usar charAt para olhar cada dígito. Outra forma é ir achando o resto da divisão por 10 (veja a documentação de BigInteger.)

Isso você pode fazer (você não pode simular um array usando uma String, pelo enunciado).

O problema é digno de TopCoder mesmo. Ontem à noite fiquei tentando resolvê-lo também.

Partir do pressuposto que o problema é uma permutação de vários dígitos, ordenados decrescentemente.

Daí fiz um método permutar, que é basicamente a implementação do Bubble Sort indo de trás pra frente, só que ele só trabalha com um passo da ordenação por vez (yield), e com o resultado eu comparo a divisibilidade.

Só empaquei na parte que na verdade o problema não é só de permutação, mas também permutação das partes do conjunto. 321 além de ter 312, 231, 213, 132, e 123, tem também 32, 31, 23, 21, 13, 12, 3, 2 e 1 (e vazio).

Por isso que eu falei que estava pensando que teria alguma recursividade… To tentando achar um padrão pra ver se consigo.

Nuosss… Thingol… boa idéi da divisão sucessiva por 10!!! :idea: :idea: :idea: :idea:
Valew!!! Acho que pode dar certo!!! :smiley:

Pega os algarismos do numero, coloca tb em ordem decrescente. Depois basta ir comparando as duas listas de algarismos para ver se o seu numero pode ser formado pelos algarismos da lista. EX: lista: 11122223333 numero:22113
ordem decrescente do numero 112233.
Para cada elemento do novo numero em ordem decrescente, desempilhe das duas listas se forem iguais, e desempilhe só da lista inicial forem diferentes. Se a lista inicial estiver vazia e a lista do numero decrescente nao, isso implica que o numero nao pode ser formado. Caso contrario o numero pode ser formado e vc armazena ele como sendo maior.

Faça isso para todos múltiplos, armazenando o valor do maior múltiplo que pode ser formado, até que o numero de algarismos deles excedam o numero da lista inicial (no seu caso 49).

Ao final, vc terá armazenado o maior multiplo…