MAC 2166 Introdução à Computação para Engenharia


PROVA 1

QUESTÃO 1.

Simule a execução do programa abaixo, destacando a sua saída.
A saída do programa consiste de tudo que resulta dos
comandos printf.

int main()
{
  int a, b, c, d, e, nusp;

  printf("Entre com o seu no. USP: ");
  scanf("%d", &nusp);  /* Use aqui o seu número USP */
  printf("nusp = %d\n", nusp);

  d = nusp % 1000;
  a = d / 100;
  b = d / 10;
  b = b - a * 10; 
  c = d % 10 ;
  printf("a = %d b = %d c = %d d = %d\n", a, b, c, d);

  if (a < b) {
    e = a; a = b; b = e;
  }  
  printf("a = %d b = %d c = %d\n", a, b, c);


  if (c > a && c <= b)
     printf("Perfeito.\n");
  else
     printf("Otimo.\n");

  a = 0; 
  while ( c > 0 || a < 5 ) {
    b = c % 2;
    printf("b = %d\n", b);
    c = c / 2;
    a = a + 1;
  }
  
  return 0;
}


SOLUÇÃO.

A resposta depende, essencialmente, do último dígito do número USP.
Teste com o seu no. USP e compare a resposta.

(0) último dígito do número USP == 0

Entre com o seu no. USP: 1230

Saída:

nusp = 1230
a = 2 b = 3 c = 0 d = 230
a = 3 b = 2 c = 0
Otimo.
b = 0
b = 0
b = 0
b = 0
b = 0

(1) último dígito do número USP == 1

Entre com o seu no. USP: 1231

Saída:

nusp = 1231
a = 2 b = 3 c = 1 d = 231
a = 3 b = 2 c = 1
Otimo.
b = 1
b = 0
b = 0
b = 0
b = 0

(2) último dígito do número USP == 2

Entre com o seu no. USP: 1232

Saída:

nusp = 1232
a = 2 b = 3 c = 2 d = 232
a = 3 b = 2 c = 2
Otimo.
b = 0
b = 1
b = 0
b = 0
b = 0

(3) último dígito do número USP == 3

Entre com o seu no. USP: 1233 

Saida:

nusp = 1233
a = 2 b = 3 c = 3 d = 233 
a = 3 b = 2 c = 3 
Otimo.
b = 1
b = 1
b = 0
b = 0
b = 0

(4) último dígito do número USP == 4

Entre com o seu no. USP: 1234 

Saída:

nusp = 1234
a = 2 b = 3 c = 4 d = 234 
a = 3 b = 2 c = 4 
Otimo.
b = 0
b = 0
b = 1
b = 0
b = 0

(5) último dígito do número USP == 5

Entre com o seu no. USP: 1235 

Saída

nusp = 1235
a = 2 b = 3 c = 5 d = 235 
a = 3 b = 2 c = 5 
Otimo.
b = 1
b = 0
b = 1
b = 0
b = 0

(6) último dígito do número USP == 6

Entre com o seu no. USP: 1236 

Saída:

nusp = 1236
a = 2 b = 3 c = 6 d = 236 
a = 3 b = 2 c = 6 
Otimo.
b = 0
b = 1
b = 1
b = 0
b = 0

(7) último dígito do número USP == 7

Entre com o seu no. USP: 1237 

Saída:

nusp = 1237
a = 2 b = 3 c = 7 d = 237 
a = 3 b = 2 c = 7 
Otimo.
b = 1
b = 1
b = 1
b = 0
b = 0

(8) último dígito do número USP == 8

Entre com o seu no. USP: 1238 

Saída:

nusp = 1238
a = 2 b = 3 c = 8 d = 238 
a = 3 b = 2 c = 8 
Otimo.
b = 0
b = 0
b = 0
b = 1
b = 0

(9) último dígito do número USP == 9

Entre com o seu no. USP: 1239 

Saída:

nusp = 1239
a = 2 b = 3 c = 9 d = 239 
a = 3 b = 2 c = 9 
Otimo.
b = 1
b = 0
b = 0
b = 1
b = 0

----------------------------------------------------------------
QUESTÃO 2.

O programa abaixo tenta resolver o seguinte problema:

  ``Dados n>0 e uma seqüência com n inteiros, determinar quantos segmentos
    de números iguais consecutivos compõem a seqüência.''

Por exemplo, a seguinte seqüência 

      5  -2  -2  1  4  4  4  0  0  5  5

é composta de 6 segmentos de números iguais consecutivos.


#include 

int main(){
   int n, num, ant, nseg;
 
   scanf("%d", &n);
   ant = 0;
   nseg = 0;
   while(n > 0) {
      scanf("%d", &num);
      if (ant == num) {
        nseg = nseg + 1;
      }
      n = n - 1;
   }
 
   printf("Ha' %d segmentos de numeros iguais consecutivos.\n", nseg);
   return 0;
}

O programa está com erro(s) de lógica.

a) Mostre uma entrada válida para a qual o programa não funciona e a
saída correspondente.

b) Escreva um programa em C que resolve o problema. O seu programa
pode ou não estar baseado no programa acima.

SOLUÇÃO de (a).

para n = 1 e sequencia = 1 a resposta é 0 [deveria ser 1].

para n = 2 e sequencia = 1, 1 a resposta é 0 [deveria ser 1].

para n = 2 e sequencia = 1, 2 a resposta é 0 [deveria ser 1].

para n = 2 e sequencia = 1, 0 ou 0, 1 a resposta é 1 [deveria ser 2].

para n = 5 e sequencia = 0, 1, 0, 1, 0 a resposta é 3 [deveria ser 5].

Na realidade, o programa dado resolve um outro problema:

  "Dados n > 0 e uma seqüência com n números inteiros, determinar o
   número de zeros na seqüências."


SOLUÇÃO de (b)

Este é o exercício 1.21 da lista de exercícios, veja

http://www.ime.usp.br/~macmulti/exercicios/inteiros/index.html

[Um exercício semelhante, apesar de um pouco mais difícil, é o exercício
 seguinte, o 1.22.]

/*
 * VERSÃO 1: com contador de número lidos e comando for
 */
#include 

int main()
{
  int n, /* comprimento da sequencia */
      i, /* número de elementos lidos */
      anterior, /* penultimo numero lido da sequencia */
      atual,    /* ultimo numero lido da sequancia */
      no_seg;   /* contador de segmentos de numeros iguais */

  printf("Entre com o numero de elementos da sequencia:");
  scanf("%d", &n);

  printf("Entre com o 1o. numero de sequencia: ");
  scanf("%d", &anterior); 

  no_seg = 1;

  for (i = 1; i < n; i++) 
    {
      /* 1. Leia o proximo numero */
      printf("Entre com o %do. numero de sequencia: ", i);
      scanf("%d", &atual);

      /* 2. Comecou outro segmento? */
      if (anterior != atual)
        {
          /* temos mais um segmento */
	  no_seg = no_seg + 1;
	}
      
      /* 3. O atual de hoje e' o anterior da proxima iteracao ;-) */
      anterior = atual;
    }  

  printf("Ha' %d segmentos de numeros iguais consecutivos.\n", no_seg);
 
  return 0;
}

/*
 * VERSÃO 2. Com contador de número lidos e comando while
 */
#include 

int main()
{ 
  int n, /* comprimento da sequencia */
      i, /* número de elementos lidos */
      anterior, /* penultimo numero lido da sequencia */
      atual,    /* ultimo numero lido da sequancia */
      no_seg;   /* contador de segmentos de numeros iguais */

  printf("Entre com o numero de elementos da sequencia:");
  scanf("%d", &n);

  printf("Entre com o 1o. numero de sequencia: ");
  scanf("%d", &anterior); 

  no_seg = 1;

  i = 1;
  while (i < n) 
    {
      /* 1. Leia o proximo numero */
      printf("Entre com o %do. numero de sequencia: ", i);
      scanf("%d", &atual);

      /* 2. Comecou outro segmento? */
      if (anterior != atual)
        {
          /* temos mais um segmento */
	  no_seg = no_seg + 1;
	}
      else
        {
         /* O atual de hoje e' o anterior da proxima iteracao ;-) */
          anterior = atual;
        }
      i = i + 1;
    }  

  printf("Ha' %d segmentos de numeros iguais consecutivos.\n", no_seg);
 
  return 0;
}

/*
 * VERSÃO 3: nesta versão a variável n indica elementso da seqüência ainda
 *           precisam ser lidos.
 */

#include 

int main()
{ 
  int n, /* numero de elementos da sequencia que ainda precisam
            ser lidos */
      anterior, /* penultimo numero lido da sequencia */
      atual,    /* ultimo numero lido da sequancia */
      no_seg;   /* contador de segmentos de numeros iguais */

  printf("Entre com o numero de elementos da sequencia:");
  scanf("%d", &n);


  printf ("Entre com o 1o. numero de sequencia: ");
  scanf("%d", &anterior); 
  n = n - 1;

  no_seg = 1;

  /* n > 0 significa que ainda existem numero da seq para serem lidos. */
  while (n > 0) 
    {
      /* 1. Leia o proximo numero */
      printf("Entre com o %do. numero de sequencia: ", i);
      scanf("%d", &atual);

      /* 2. Comecou outro segmento? */
      if (anterior != atual)
        {
          /* temos mais um segmento */
	  no_seg = no_seg + 1;
	}
      else
        {
         /* O atual de hoje e' o anterior da proxima iteracao ;-) */
          anterior = atual;
        } 
      i = i + 1;
    }  

  printf("Ha' %d segmentos de numeros iguais consecutivos.\n", no_seg);
 
  return 0;
}

----------------------------------------------------------------
QUESTÃO 3.

Dados dois números inteiros positivos a e b diz-se que 
b encaixa em a  se b é um número que corresponde aos últimos
digitos de a.

Exemplos:

(1) a = 567890  b = 890,   b encaixa em a;
(2) a = 1234    b = 1234,  b encaixa em a;
(3) a = 2457    b = 245,   b não encaixa em a;
(4) a = 457     b = 2457,  b não encaixa em a.
          
Escreva um programa em C que, dados dois números inteiros a > 0 e
b > 0, determina se b encaixa em a.


Exemplos:

Entrada: 567890   890   Saída: encaixa
Entrada:   1234  1234   Saída: encaixa
Entrada:   2457   245   Saída: nao encaixa
Entrada:    457  2457   Saída: nao encaixa

SOLUÇÃO.

/*
 * VERSÃO 1: `descasca' a e b e compara os dígitos.
 */

#include 

int main()
{
  int a, b,   /* dados do problema */
    digito_a, /* ultimo digito de a */ 
    digito_b, /* ultimo digito de b */ 
    encaixa;  /* indica se b encaixa em a (encaixa == 1) ou nao 
		 (encaica == 0) */         

  printf("Entre com a e b: ");
  scanf("%d %d", &a, &b);

  /* b encaixa em a ate' que se prove o contraio */
  encaixa = 1;

  while (b != 0 && encaixa == 1) 
    {
      digito_a = a % 10;
      digito_b = b % 10;

      if (digito_a != digito_b) 
        {
	  encaixa = 0;
        }

      /* prepara a e b para a proxima iteracao */
      a = a / 10;
      b = b / 10;
    }

  if (encaixa == 1)
    {
      printf("encaixa\n");
    }
  else
    {
      printf("nao encaixa\n");
    }

  return 0;
}  

/*
 * VERSAO 2:
 */

#include 

int main()
{
    int a, b,   /* dados do problema */
      pot10;    /* usado para calcular a menors potencia de 10 maior que b */

  printf("Entre com a e b: ");
  scanf("%d %d", &a, &b);

  /* calcula a menor potencia de 10 maior que b */
  pot10 = 1;
  while (pot10 <= b) 
    {
      pot10 = pot10 * 10;
    }

  if (a % pot10 == b % pot10)
    {
      printf("encaixa\n");
    }
  else
    {
      printf("nao encaixa\n");
    }

  return 0;
}  



----------------------------------------------------------------
QUESTÃO 4.

Escreva um programa em C que, dado um inteiro n, decide se existem
dois inteiros cuja soma dos quadrados é igual a n. Em caso
afirmativo, seu programa imprime SIM e dois inteiros cuja soma dos
quadrados é n. Em caso negativo, seu programa imprime NAO.
No exemplo abaixo,
0 = 02 + 02, 1 = 02 + 12, 5 = 12 + 22, 8 = 22 + 22, 9 = 02 + 32.
Exemplos:

Entrada: -1      Saída: NAO
Entrada:  0      Saída: SIM. Os inteiros sao 0 e 0
Entrada:  1      Saída: SIM. Os inteiros sao 0 e 1
Entrada:  5      Saída: SIM. Os inteiros sao 1 e 2 
Entrada:  6      Saída: NAO
Entrada:  8      Saída: SIM. Os inteiros sao 2 e 2 
Entrada:  9      Saída: SIM. Os inteiros sao 0 e 3 

SOLUÇÃO.

/*
 * VERSÃO 1: simples e direta.
 */

int main()
{
  int n,    /* dado do problema */
    i, j,   /* candidatos a i*i + j*j == n */
    achou,  /* indica se i*i + j*j == n (achou == 1) ou nao 
		 (achou == 0) */ 
    i_sol, j_sol; /* quando achou == 1 vale que 
                    i_sol * i_sol + j_sol * j_sol == n */        

  /* Leia o dado de entrada */
  printf("Entre com n: ");
  scanf("%d", &n);

  /* i*i + j*j != n ate que se prove o contrario */
  achou = 0;

  for (i = 0; i <= n; i++)
    {
      for (j = 0; j <= n; j++)
	{
	  if (i*i + j*j == n) 
            {
              achou = 1;
              i_sol = i;
              j_sol = j;
            }
	}
    }     

  if (achou == 1)
    {
      printf("SIM. Os inteiros sao %d e %d.\n", i_sol, j_sol);
    }
  else
    {
      printf("NAO\n");
    }

  return 0;
}  
  


/* 
 * VERSÃO 2: esta versão pára assim que encontra i e j tais que
 *           i*i + j*j == n.
 */

#include 

int main()
{
  int n,    /* dado do problema */
    i, j,   /* candidatos a i*i + j*j == n */
    achou,  /* indica se i*i + j*j == n (achou == 1) ou nao 
		 (achou == 0) */ 
    i_sol, j_sol; /* quando achou == 1 vale que 
                    i_sol * i_sol + j_sol * j_sol == n */        

  /* Leia o dado de entrada */
  printf("Entre com n: ");
  scanf("%d", &n);

  /* i*i + j*j != n ate que se prove o contrario */
  achou = 0;

  for (i = 0; i <= n && achou == 0; i++)
    {
      for (j = 0; j <= n && achou == 0; j++)
	{
	  if (i*i + j*j == n) 
            { 
	      achou = 1;
              i_sol = i;
              j_sol = j;
            }
	}
    }     

  if (achou == 1)
    {
      printf("SIM. Os inteiros sao %d e %d.\n", i_sol, j_sol);
    }
  else
    {
      printf("NAO\n");
    }

  return 0;
}  

/*
 * VERSÃO 3: versao que usa mais duas variáveis extras: ii (== i*i) e
 *           jj (== j*j).
 */

#include 

int main()
{
  int n,    /* dado do problema */
    i, j,   /* candidatos a i*i + j*j == n */
    ii,     /* ii == i * i */
    jj,     /* jj == j * j */
    achou,  /* indica se i*i + j*j == n (achou == 1) ou nao 
		 (achou == 0) */ 
    i_sol, j_sol; /* quando achou == 1 temos que 
                    i_sol * i_sol + j_sol * j_sol == n */        

  /* Leia o dado de entrada */
  printf("Entre com n: ");
  scanf("%d", &n);

  /* i*i + j*j != n ate que se prove o contrario */
  achou = 0;

  i  = 0;
  ii = 0;
  while (ii <= n && achou == 0) /* podemos para assim que i*i > n */ 
    {
      j  = 0;
      jj = 0;
      while(jj <= n - ii && achou == 0) 
        {
	  if (ii + jj == n) 
            {
              /* vale que i*i + j*j == n */
	      achou = 1;
              i_sol = i;
              j_sol = j;
            }
          
          /* prepara j e jj para a proxima iteracao */
	  j  = j + 1;
	  jj = j * j;
	}

      /* prepara i e ii para a proxima iteracao */
      i  = i + 1;
      ii = i * i;
    }     

  if (achou == 1)
    {
      printf("SIM. Os inteiros sao %d e %d.\n", i_sol, j_sol);
    }
  else
    {
      printf("NAO\n");
    }

  return 0;
}  
  

/* 
 * VERSÃO ERRADA. Alguém sabe dizer porque a versão abaixo não funciona?
 *                O erro é meio sutil. 
 */

#include 

int main()
{
  int n,    /* dado do problema */
    i, j,   /* candidatos a i*i + j*j == n */
    achou;  /* indica se i*i + j*j == n (achou == 1) ou nao 
		 (achou == 0) */

  /* Leia o dado de entrada */
  printf("Entre com n: ");
  scanf("%d", &n);

  /* i*i + j*j != n ate que se prove o contrario */
  achou = 0;

  for (i = 0; i <= n && achou == 0; i++)
    {
      for (j = 0; j <= n && achou == 0; j++)
	{
	  if (i*i + j*j == n) 
            { 
	      achou = 1;
            }
	}
    }     

  if (achou == 1)
    {
      printf("SIM. Os inteiros sao %d e %d.\n", i, j);
    }
  else
    {
      printf("NAO\n");
    }

  return 0;
}  



Last modified: Fri Apr 12 14:41:47 EST 2002