Comandos de Repetição & Operadores / e % com inteiros (Divisão inteira e Resto)

Problema 1:

Dado um número inteiro n>0, verificar se este número contém dois dígitos adjacentes iguais.
#include <stdio.h>

int main(){
  int n,r,ant,adjiguais = 0;

  printf("Digite o valor de n: ");
  scanf("%d",&n);
  ant = n % 10;
  n = n / 10;  
  while(n > 0){
    r = n % 10;
    if(ant == r)
      adjiguais = 1;
    ant = r;
    n = n / 10;
  }
  if(adjiguais)
    printf("Contém adjacentes iguais.\n");
  else
    printf("Não contém adjacentes iguais.\n");

  return 0;
}
  
Uma segunda solução usando uma condição extra de parada do laço.
Quando adjiguais recebe 1 (Verdadeiro), seu valor não é mais alterado, logo não há necessidade de continuar o laço nesse caso:
#include <stdio.h>

int main(){
  int n,r,ant,adjiguais = 0;

  printf("Digite o valor de n: ");
  scanf("%d",&n);
  ant = n % 10;
  n = n / 10;  
  while(n > 0 && !adjiguais){
    r = n % 10;
    if(ant == r)
      adjiguais = 1;
    ant = r;
    n = n / 10;
  }
  if(adjiguais)
    printf("Contém adjacentes iguais.\n");
  else
    printf("Não contém adjacentes iguais.\n");

  return 0;
}
  
Outra solução alternativa, inicializando a variável ant com um dígito inválido, ao invés de ler o primeiro dígito de n fora do laço. Com essa alteração, a condição do laço ant == r nunca será verdadeira na primeira iteração do laço.
#include <stdio.h>

int main(){
  int n,r,ant,adjiguais = 0;

  printf("Digite o valor de n: ");
  scanf("%d",&n);
  ant = 10; /*dígito inválido > 9*/
  while(n > 0 && !adjiguais){
    r = n % 10;
    if(ant == r)
      adjiguais = 1;
    ant = r;
    n = n / 10;
  }
  if(adjiguais)
    printf("Contém adjacentes iguais.\n");
  else
    printf("Não contém adjacentes iguais.\n");

  return 0;
}
  

Problema 2:

Dados dois inteiros calcular o máximo divisor comum (MDC) entre eles.

O MDC de dois números inteiros é o maior número inteiro que divide ambos sem deixar resto.

Exemplos:

#include <stdio.h>

int main(){
  int a,b,m,i,mdc=1;
  printf("MDC entre A e B:\n");
  printf("Entre com A: ");
  scanf("%d",&a);
  printf("Entre com B: ");
  scanf("%d",&b);
  if(a == 0 && b == 0){
    printf("MDC(0, 0) não existe pois todo inteiro não-nulo é divisor de zero.\n");
    return 0;
  }
  else if(a == 0)
    mdc = b;
  else if(b == 0)
    mdc = a;
  else{
    if(a < b)
      m = a;
    else
      m = b;
  
    for(i=2; i <= m; i++){
      if(a%i == 0 && b%i == 0)
        mdc = i;
    }
  }
  printf("MDC = %d\n",mdc);
  return 0;
}
  

Segunda solução: Nessa segunda solução, realizamos o laço a partir do maior valor candidato a MDC em direção aos menores, o que permite encerrar o laço assim que o primeiro divisor comum for encontrado. Será assumido que a > 0 e b > 0 a fim de simplificar o código.

#include <stdio.h>

int main(){
  int a,b,m;
  printf("MDC entre A e B:\n");
  printf("Entre com A: ");
  scanf("%d",&a);
  printf("Entre com B: ");
  scanf("%d",&b);

  if(a < b)
    m = a;
  else
    m = b;

  for(; m > 0 ; m--){
    if(a%m == 0 && b%m == 0)
      break;
  }
  printf("MDC = %d\n",m);
  return 0;
}
  
Terceira solução: Dados dois inteiros positivos calcular o máximo divisor comum (MDC) entre eles usando o algoritmo de Euclides.

Algoritmo de Euclides: Para dois números A e B:

  1. Se A ≥ B: MDC(A,B) = MDC(A-B, B) = MDC(A%B, B) = MDC(B, A%B)
  2. Se A < B: MDC(A,B) = MDC(B,A)
A repetição deste processo irá gerar sucessivamente números menores, até convergir em zero. Nesse momento, o MDC é o outro número inteiro, maior que zero.

#include <stdio.h>

int main(){
  int a,b,r,t;
  printf("MDC entre A e B:\n");
  printf("Entre com A: ");
  scanf("%d",&a);
  printf("Entre com B: ");
  scanf("%d",&b);

  if(a < b){
    t = a;
    a = b;
    b = t;
  }
  while(b > 0){
    r = a%b;
    a = b;
    b = r;
  }
  printf("MDC = %d\n",a);
  return 0;
}
  
Na verdade o primeiro "if" não é necessário e pode ser omitido, pois a primeira iteração do laço irá naturalmente inverter o conteúdo das variáveis a e b quando a < b.
#include <stdio.h>

int main(){
  int a,b,r;
  printf("MDC entre A e B:\n");
  printf("Entre com A: ");
  scanf("%d",&a);
  printf("Entre com B: ");
  scanf("%d",&b);

  while(b > 0){
    r = a%b;
    a = b;
    b = r;
  }
  printf("MDC = %d\n",a);
  return 0;
}
  

Laços aninhados (repetições encaixadas)

Problema 1:

Dado um número inteiro n, n>1, imprimir sua decomposição em fatores primos, indicando também a mutiplicidade de cada fator. Por exemplo, para n=600, a saída deverá ser:
#include <stdio.h>

int main(){
  int n,fator = 2,mult;
  printf("Digite n: ");
  scanf("%d",&n);
  printf("Decomposição de %d em fatores primos:\n",n);
  while(n > 1){
    mult = 0;
    while(n%fator == 0){
      n /= fator;
      mult += 1;
    }
    if(mult > 0)
      printf("fator %d multiplicidade %d\n",fator,mult);
    fator += 1;
  }
  return 0;
}
  

Problema 2:

Dados um número inteiro n>0 e uma sequência com n números inteiros maiores do que zero, determinar o máximo divisor comum entre eles. Por exemplo, para a entrada
3 42 30 105
o seu programa deve escrever o número 3.

DICA: O MDC é uma operação associativa:

MDC(A,B,C,D) = MDC(MDC(A,B),C,D) = MDC(MDC(MDC(A,B),C),D)
#include <stdio.h>

int main(){
  int n,i,num,mdc,a,b,r;

  printf("Digite n: ");
  scanf("%d",&n);
  printf("Digite um num: ");
  scanf("%d",&mdc);
  for(i=1; i < n; i++){
    printf("Digite um num: ");
    scanf("%d",&num);
    a = mdc;
    b = num;
    /*MDC entre A e B:*/
    while(b > 0){
      r = a%b;
      a = b;
      b = r;
    }
    mdc = a;
  }
  printf("MDC = %d\n",mdc);
  return 0;
}
  

Problema 3:

Sabe-se que cada número da forma n3 é igual a soma de n ímpares consecutivos.
Exemplos: 13= 1,   23= 3 + 5,   33= 7 + 9 + 11,   43= 13 + 15 + 17 + 19.

Dado um número inteiro m, m>0, determinar os ímpares consecutivos cuja soma é igual a n3, para n assumindo valores de 1 a m.

Solução 1:

#include <stdio.h>

int main(){
  int m,n,soma,inic,i;
  
  printf("Digite m: ");
  scanf("%d", &m);
  n = 1;
  while(n <= m){
    inic = 1;
    soma = 0;
    while(soma != n*n*n){
      soma = 0;
      for(i = 1; i <= n; i += 1){
        soma += inic + (i-1)*2;
      }
      inic += 2;
    }
    inic -= 2;

    printf("%d = ",n*n*n);
    printf("%d ",inic);
    for(i = 2; i <= n; i += 1){
      printf("+ %d ",inic + (i-1)*2);
    }
    printf("\n");
    n += 1;
  }
  return 0;
}
  

Solução 2:

Evita o laço mais interno, aplicando a fórmula da soma dos termos da PA.

#include <stdio.h>

int main(){
  int m,n,soma,inic,i;
  
  printf("Digite m: ");
  scanf("%d", &m);
  n = 1;
  while(n <= m){
    inic = 1;
    soma = 0;
    while(soma != n*n*n){
      soma = ((inic + inic + (n-1)*2)*n)/2;
      inic += 2;
    }
    inic -= 2;

    printf("%d = ",n*n*n);
    printf("%d ",inic);
    for(i = 2; i <= n; i += 1)
      printf("+ %d ",inic + (i-1)*2);
    printf("\n");
    n += 1;
  }
  return 0;
}
  

Solução 3:

Solução praticamente idêntica a anterior. Apenas foram mudadas a ordem de alguns comandos e a inicialização de inic, de modo a evitar o comando inic -= 2; após o laço mais interno.

#include <stdio.h>

int main(){
  int m,n,soma,inic,i;
  
  printf("Digite m: ");
  scanf("%d", &m);
  n = 1;
  while(n <= m){
    inic = -1;
    soma = 0;
    while(soma != n*n*n){
      inic += 2;
      soma = ((inic + inic + (n-1)*2)*n)/2;
    }
    printf("%d = ",n*n*n);
    printf("%d ",inic);
    for(i = 2; i <= n; i += 1)
      printf("+ %d ",inic + (i-1)*2);
    printf("\n");
    n += 1;
  }
  return 0;
}
  

Solução 4:

Solução mais compacta, aproveitando o fato de que o último termo de uma sequência, e o início da próxima são ímpares consecutivos.

#include <stdio.h>

int main(){
  int m,n,imp,i;

  printf("Digite m: ");
  scanf("%d",&m);
  n = 1;
  imp = 1; /*primeiro dos ímpares de uma sequência que soma n^3*/
  while(n <= m){
    printf("%d = ",n*n*n);
    printf("%d ",imp);
    for(i = 2; i <= n; i += 1){
      imp += 2;
      printf("+ %d ",imp);
    }
    printf("\n");
    imp += 2;  /*início da próxima sequência*/
    n += 1;
  }
  return 0;
}