Fazer um programa em C que leia um número e imprima se ele é ou não um número triangular. Um número triangular é aquele que é o produto de três números consecutivos. Por exemplo: 24=2 * 3 * 4 .

Passo 1

O enunciado pede que eu faça um programa em C que:
  • Leia um número (entrada).
  • Imprima se esse número é ou não um número triangular, onde um número triangular aqui é definido como o produto de três números inteiros consecutivos (por exemplo, 24 = 2 \cdot 3 \cdot 4).
Informações relevantes dadas:
  • Exemplo: 24 = 2 \cdot 3 \cdot 4.
  • Resultado esperado: uma mensagem indicando se o número lido é triangular ou não.
Assunções que vou adotar (porque o enunciado não especificou detalhes de entrada/saída):
  • A entrada será um número inteiro não-negativo que caiba em um tipo inteiro com sinal largo (vou usar unsigned long long para cobrir números grandes).
  • Para a interpretação do problema consideramos triângulos formados por três inteiros consecutivos \,k, k+1, k+2 com k \ge 0. (Observação: existe produto de três consecutivos negativos que dá negativos, mas o exemplo e o uso típico consideram números não-negativos.)

Passo 2

Entendendo a propriedade matemática que vamos testar:
  • Queremos verificar se existe um inteiro \,k tal que
n = k\cdot (k+1)\cdot (k+2).
  • Se encontrarmos esse \,k, então n é triangular; caso contrário, não é.
Explicação didática dessa equação:
  • A expressão k(k+1)(k+2) é um polinômio cúbico em k.
  • Para k\ge 0 essa função cresce com k (é estritamente monótona crescente para k\ge0), então ao testar k em ordem crescente, assim que o produto ultrapassar n podemos parar — não há necessidade de testar valores maiores.

Passo 3

Escolha do método de resolução (por que não tentar resolver a equação simbolicamente?):
  • Poderíamos tentar resolver a equação cúbica para k, mas isso envolve raízes e arredondamentos, e é desnecessariamente complicado para um programa de prova.
  • Método escolhido: busca direta (iterativa) em k = 0,1,2,\dots calculando p(k)=k(k+1)(k+2) até que p(k)=n (sucesso) ou p(k)>n (fracasso). Esse método é simples, robusto e fácil de implementar sem depender de bibliotecas extras.
  • Complexidade: se k^3 \approx n, então k \approx n^{1/3}, logo o laço tem cerca de O(n^{1/3}) iterações — perfeitamente aceitável para tamanhos razoáveis de n.

Passo 4

Problema prático importante: evitar overflow ao multiplicar
  • Em C, ao calcular k\cdot(k+1)\cdot(k+2) pode ocorrer overflow se os valores forem grandes.
  • Estratégia segura:
    1. Antes de efetuar uma multiplicação que pode estourar, usar divisões para checar se a multiplicação seria maior que n. Ex.: para saber se k\cdot(k+1) > n sem multiplicar, verificar se k \neq 0 e \left\lfloor \dfrac{n}{k}\right\rfloor < k+1. Se isso for verdade, então k(k+1)>n e, portanto, k(k+1)(k+2)>n — podemos parar.
    2. Só efetuar a multiplicação quando tivermos certeza de que o resultado cabe e não ultrapassa n.
  • Assim garantimos que nunca multiplicamos dois números grandes que causariam wrap-around silencioso e resultado incorreto.

Passo 5

Descrição passo a passo do algoritmo que vamos implementar em C:
  1. Ler n (tipo unsigned long long).
  2. Para k = 0,1,2,\dots:
    • Verificar se k\cdot(k+1) > n usando divisão segura; se for, parar (não é triangular).
    • Calcular a = k\cdot(k+1) (aqui é seguro porque garantimos a \le n).
    • Verificar se a\cdot(k+2) > n usando divisão segura; se for, parar (não é triangular).
    • Calcular p = a\cdot(k+2).
    • Se p == n, então é triangular — sucesso.
    • Se p > n, parar (não é triangular).
  3. Se nenhuma iteração encontrou igualdade, imprimir que não é triangular.
Observações de implementação:
  • Começamos em k=0 porque 0\cdot1\cdot2=0 e 0 é um caso válido (se a entrada for 0 devolveremos que é triangular).
  • Usamos condições com divisão inteira para garantir segurança contra overflow antes de multiplicar.

Passo 6

Como traduzir isso para C (detalhes práticos de leitura e saída):
  • Leitura: usar scanf("%llu", &n) para unsigned long long n.
  • Saída: imprimir uma frase clara em português, por exemplo:
    • Se for triangular: “O numero \ldots e triangular.\n”
    • Se não for: “O numero \ldots nao e triangular.\n”
  • Eu sei que você pode preferir saída curta (SIM/NAO). Se você precisar de formato específico para um juiz automático, adapte as mensagens. Aqui eu deixo mensagens descritivas para facilitar entendimento na prova manual.

Passo 7

Exemplo de execução mental com n=24 (isso serve de “aula prática”):
  • k=0: 0\cdot1\cdot2 = 0 \neq 24.
  • k=1: 1\cdot2\cdot3 = 6 \neq 24.
  • k=2: 2\cdot3\cdot4 = 24 -> achamos p=24, então o programa imprime que é triangular.
    Isso ilustra bem a busca incremental: paramos no k certo.

Passo 8

Casos especiais e dicas para prova:
  • Entrada n=0: nossa implementação retorna “triangular” (porque 0 = 0\cdot1\cdot2).
  • Entrada pequena como 1,2,3: não triangular (nenhum produto de três consecutivos dá esses valores).
  • Se o enunciado exigir aceitar negativos ou considerar produtos de três consecutivos negativos, o código precisa ser adaptado — aqui assumimos n\ge 0. Se quiser, posso depois mostrar a versão que aceita inteiros negativos (procura k negativo também).
  • Sempre explique no enunciado da prova qual convenção você está usando (por exemplo, “assumo n inteiro não-negativo”).

Passo 9

Código completo em C (implementação segura contra overflow e com saída em português).
  • O código abaixo implementa exatamente o algoritmo descrito e usa verificações por divisão antes de multiplicar para evitar overflow silencioso.

Resposta

#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned long long n;
if (scanf("%llu", &n) != 1) return 0;
int found = 0;
for (unsigned long long k = 0;; ++k) {
    /* Antes de calcular a = k*(k+1), verificamos se k*(k+1) > n sem multiplicar */
    if (k != 0 && n / k < (k + 1)) break; /* então k*(k+1) > n -> produto final > n */

    unsigned long long a = k * (k + 1); /* seguro pois a <= n */
    /* Antes de calcular p = a*(k+2), verificamos se a*(k+2) > n sem multiplicar */
    if (a != 0 && n / a < (k + 2)) break; /* então a*(k+2) > n -> produto final > n */

    unsigned long long p = a * (k + 2); /* seguro */
    if (p == n) { found = 1; break; }
    if (p > n) break;
    /* caso p < n, continua com próximo k */
}

if (found)
    printf("O numero %llu e triangular.\n", n);
else
    printf("O numero %llu nao e triangular.\n", n);

return 0;
}

Exercícios relacionados