MAC2166  Introdução à Computação para a Engenharia

Prova 2

QUESTÃO 1

  Simule a execução do programa abaixo, destacando a sua saída. A saída do programa consiste em tudo que resulta dos comandos printf's e o número digitado pelo usuário. O dado de entrada (variável nusp) é o seu número USP.
Dica: mesmo que você não saiba uma parte da simulação, continue até o final.
# include <stdio.h>


int f1(int a, int b, int c)
{
  int z;

  z = a + 2 * b; 
  a = b - c;
  b = b + c;     
  z = z - a - b;

  return z;
}

int f2(int *a, int *b, int c)
{
  int w, z;

   z = *a - c;
   w = *b - c;
  *a =  z - w;
  *b = *a - z;

  return z;
}

int main()
{
  int nusp, t, n, m, a, b, c, d;

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

  t = nusp % 10;
  n = t + 5;
  m = t + 7;
  printf ("t=%d n=%d m=%d\n", t, n, m);

  a = n;
  b = m;
  c = a + b;
  d = c - f1(c, b, a) + b;
  printf ("a=%d b=%d c=%d d=%d\n", a, b, c, d);

  a = n;
  b = m;
  c = a + b;
  d = f2(&c, &a, b) + b;
  printf ("a=%d b=%d c=%d d=%d\n", a, b, c, d);

  return 0;
}

SOLUÇÃO
A resposta depende do último dígito do seu número USP. Teste com o seu no. USP e compare com a resposta abaixo.

(0) nusp % 10 == 0.

    Entre com seu no. USP: 1234560
    nusp = 1234560
    t=0 n=5 m=7
    a=5 b=7 c=12 d=7
    a=2 b=7 c=7 d=12

(1) nusp % 10 == 1.

    Entre com seu no. USP: 1234561
    nusp = 1234561
    t=1 n=6 m=8
    a=6 b=8 c=14 d=8
    a=2 b=8 c=8 d=14

(2) nusp % 10 == 2.

    Entre com seu no. USP: 1234562
    nusp = 1234562
    t=2 n=7 m=9
    a=7 b=9 c=16 d=9
    a=2 b=9 c=9 d=16

(3) nusp % 10 == 3.

    Entre com seu no. USP: 1234563
    nusp = 1234563
    t=3 n=8 m=10
    a=8 b=10 c=18 d=10
    a=2 b=10 c=10 d=18

(4) nusp % 10 == 4.

    Entre com seu no. USP: 1234564          
    nusp = 1234564
    t=4 n=9 m=11
    a=9 b=11 c=20 d=11
    a=2 b=11 c=11 d=20

(5) nusp % 10 == 5.

    Entre com seu no. USP: 1234565
    nusp = 1234565
    t=5 n=10 m=12
    a=10 b=12 c=22 d=12
    a=2 b=12 c=12 d=22

(6) nusp % 10 == 6.

    Entre com seu no. USP: 1234566
    nusp = 1234566
    t=6 n=11 m=13
    a=11 b=13 c=24 d=13
    a=2 b=13 c=13 d=24

(7) nusp % 10 == 7.

    Entre com seu no. USP: 1234567
    nusp = 1234567
    t=7 n=12 m=14
    a=12 b=14 c=26 d=14
    a=2 b=14 c=14 d=26

(8) nusp % 10 == 8.

    Entre com seu no. USP: 1234568
    nusp = 1234568
    t=8 n=13 m=15
    a=13 b=15 c=28 d=15
    a=2 b=15 c=15 d=28

(9) nusp % 10 == 9.

    Entre com seu no. USP: 1234569
    nusp = 1234569
    t=9 n=14 m=16
    a=14 b=16 c=30 d=16
    a=2 b=16 c=16 d=30

QUESTÃO 2

  Para um inteiro r >= 0, denote por Kr o número
1 - 1/3 + 1/5 - . . . + (-1)r 1/(2r+1).
Assim, por exemplo, K0= 1, K1 = 2/3 = 0,666666..., K2= 13/15 = 0,866666... e K3 = 76/105 = 0,7238...

(a) Escreva uma função de protótipo

          float K(int r);
que recebe como parâmetro um inteiro r>=0 e devolve Kr.

SOLUÇÃO

 /*
 * Solucao 1:
 */
float K(int r)
{
   int   i, sinal;
   float k_r;

   k_r   = 0; 
   sinal = 1;
   for (i = 0; i <= r; i++)
     {
        k_r = k_r + sinal * (float)1/(2*i+1);
        sinal = -1 * sinal;
     }

   return k_r; 
}    

/*
 * Solucao 2: identica a solucao 1, usa while em vez de for.
 */
float K(int r)
{
   int   i, sinal;
   float k_r;

   k_r   = 0; 
   sinal = 1;
   i     = 0;
   while (i <= r)
     {
        k_r = k_r + sinal * (float)1/(2*i+1);
        sinal = -1 * sinal;
        i = i + 1;
     }

   return k_r; 
}    

    
/*
 * Solucao 3:
 */
float K(int r)
{    
   int i, sinal;
   float k_r;

   k_r   = 0;
   sinal = 1;
   for (i = 1; i <= 2*r+1; i=i+2)
     {
        k_r = k_r + sinal * 1.0/i;
        sinal = -sinal;
     }

   return k_r;     
}

/*
 * Solucao 4: 
 */
float K(int r)
{    
   int i;
   float k_r, termo;

   k_r   = 0;
   termo = 1;
   for (i = 1; i <= 2*r+1; i=i+2)
     {
        k_r = k_r + termo;
        termo = -(termo*i)/(i+2);
     }

   return k_r;     
}

(b) A função para todo x com |x|<1, é dada pela série

f(x) = (x2/2)K0 + (x6/6)K1 + (x10/10)K2 + ...  + (x4r+2)/(4r+2))K_r + ...
Escreva uma função de protótipo
          float f (float x);
que recebe como parâmetro um real x tal que |x|<1 e devolve uma aproximação de f(x) dada pela série acima, incluindo na soma todos os termos até o primeiro de valor menor que 0,001. (Ou seja, o primeiro termo de valor menor que 0,001 deve ser incluído na soma.) Utilize obrigatoriamente a função do item anterior, mesmo que você não a tenha feito.

SOLUÇÃO

 /*
 * Solucao 1:
 */
float f(float x) 
{
  int i;
  float soma, razao, termo; 

  soma  = 0;
  i     = 0; 
  razao = x*x/2;
  termo = razao*K(0);
  while (termo >= 0.001) 
    {
      soma  = soma + termo;
      i     = i + 1;
      razao = razao*x*x*x*x*(4*i-2)/(4*i+2);
      termo = razao*K(i);
    }

  /* inclui na soma o primeiro termo menor que 0.001 */
  soma = soma + termo;

return soma;
}

/*
 * Solucao 2:
 */
#define EPS 0.001

float f(float x) 
{
  int i, denominador;
  float soma, potx, razao; 

  soma  = 0;
  i     = 0; 
  potx  = x*x;
  denominador = 2;
  razao = potx/denominador;
  termo = razao*K(0);
  while (termo >= EPS) 
    {
      soma  = soma + termo;
      i     = i + 1;
      potx  = potx*x*x*x*x;
      denominador = denominador + 4;
      razao = potx/denominador;
      termo = razao*K(i);
    }

  /* inclui na soma o primeiro termo menor que 0.001 */
  soma = soma + termo;

return soma;
}


/*
 * Solucao 3: identica as solucoes anteriores. Usa o comando
 *        do-while em vez de while. 
 * OBS: muitas turmas nao viram o do-while:
 *
 *   do 
 *      {
 *        [...lista de comandos...];
 *      }
 *   while (condicao);
 *
 * e' equivalente a
 *    
 *    [...lista de comandos...];
 *    while (condicao)
 *      {
 *        [...lista de comandos...];
 *      }
 */
float f(float x) 
{
  int i, denominador;
  float soma, potx, razao; 

  soma  = 0;
  i     = -1; 
  potx  = 1/(x*x);
  denominador = -2;
  do
    {
      i     = i + 1;
      potx  = potx*x*x*x*x;
      denominador = denominador + 4;
      razao = potx/denominador;
      termo = razao*K(i);
      soma  = soma + termo;
    }
  while (termo >= 0.001);

  /* termo menor que 0.001 já foi adicionado a soma */

  return soma;
}

(c) Escreva um programa que leia um inteiro n >= 1 e uma seqüência de n números reais x1, x2, ..., xn tais que |xi|<1 para todo i, e imprima o mínimo entre f(x1),...,f(xn). Utilize obrigatoriamente a função do item anterior, mesmo que você não a tenha feito.

SOLUÇÃO

#include <stdio.h>

int main() 
{
  int n, i; 
  float x, fx, min_fx; 

  printf("Digite n: "); 
  scanf("%d", &n); 
  printf("Digite uma sequencia de %d números reais"
         " menores que 1 em valor absoluto:\n", n);

  scanf("%f", &x);
  min_fx = f(x);
  printf("f(%f) = %f\n", x, min_fx);
  for (i = 1; i <= n-1; i++) 
    {
      scanf("%f", &x);
      fx = f(x);
      printf("f(%f) = %f\n", x, fx);
      if (fx < min_fx)
        {
          min_fx = fx;
        }

    }

  printf("Menor valor = %f\n", min_fx); 
  return 0;
}

QUESTÃO 3

  Para resolver o item (b) dessa questão, considere feitas as funções
          float seno(float x); 
          float cosseno(float x);
ou seja, use-as sem ter que escrevê-las. Tais funções recebem um ângulo x em radianos e devolvem, respectivamente, o seno e o cosseno de tal ângulo.

(a) Escreva uma função de protótipo

          float graus2radianos(float a); 
ou
          double graus2radianos(double a); 
que recebe um real a, 0<=a<360, representando um ângulo em graus, e devolve o ângulo correspondente em radianos. Adote, para isso, pi=3,1416.

SOLUÇÃO

/*
 * Função que recebe o valor de um ângulo em graus e devolve
 *   o correspondente ângulo em radianos.
 */
#define PI 3.1415

float graus2radianos(float a)
{
  return a*PI/180; 
}

(b) Escreva uma função de protótipo

          void converte(float r, float a, float *x, float *y); 
ou
          void converte(double r, double a, double *x, double *y); 
que recebe dois reais r e a, representando as coordenadas polares (r,a) de um ponto onde a é o ângulo em graus, e devolve as coordenadas cartesianas desse ponto em *x e *y.

SOLUÇÃO

/*
 * Função recebe as coordenadas polares (r,a) de um ponto e
 *   devolve em (*x,*y) as coordenadas cartesianas do ponto.
 */
void converte(float r, float a, float *x, float *y)
{
  *x = r*cosseno(graus2radianos(a)); 
  *y = r*seno(graus2radianos(a)); 
}

/*
 * SOLUCAO 2
 */
void converte(float r, float a, float *x, float *y)
{
  float a_radianos;

  a_radianos = graus2radianos(a);
  *x = r*cosseno(a_radianos); 
  *y = r*seno(a_radianos); 
}

(c) Escreva um programa que leia um inteiro n>0 e uma seqüência de números reais r1,a1, r2,a2,...,rn,an, onde ri >= 0 e 0<=ai<360 para cada 1<=i<=n. Cada (ri,ai) representa as coordenadas polares de um ponto, sendo que ai é dado em graus. Seu programa deve imprimir as coordenadas cartesianas de cada ponto da seqüência. Utilize obrigatoriamente a função do item anterior, mesmo que você não a tenha feito.

SOLUÇÃO

#include <stdio.h>

int main()
{
  int n, i;
  float r, a, x, y; 

  scanf("%d", &n);
  for (i = 0; i < n; i++)
    {
      scanf("%f %f", &r, &a);
      converte(r, a, &x, &y);
      printf("Ponto (%f,%f) em coordenadas cartesianas e' "
             "(%f,%f).\n", r, a, x, y);
    }
  return 0 ;
}

 

 

 


Last modified: Mon May 17 14:52:20 BRT 2004