logo ULP

retour sommaire des sujets

Proposition de solution

Examen d'informatique IUP2

Première session 2000


 

Première Partie

Il y a plusieurs possibilités, j'en donne une mais ce n'est qu'un exemple

On peut remarquer qu'utiliser un seul tableau n'est pas une bonne idée : toutes les composante (volume) ne sont pas du même type. On pourrait dans un premier temps définir chaque type de volume sous forme d'une structure :

Puisqu'à priori on désire analyser des jouets déjà bien définis, on peut demander dès le début le nombre de sphères, cônes... Comme ces nombres ne devraient pas changer au cours du programme, on pourrait ensuite créer (dynamiquement) un tableau pour les sphères, les saisir, puis de même pour chaque type de volume. Ceci donnerait, pour la figurine proposée dans le sujet, les tableaux suivants :

Pour uniquement analyser la stabilité de l'ensemble, l'ordre n'a aucun intérêt. Si le programme devait aussi permettre de concevoir et modifier fréquemment le jouet, pas seulement en changeant les tailles, directions, disposition des volumes mais en en ajoutant et supprimant, il faudrait utiliser des listes plutôt que des tableaux. Pour d'autres utilisations du modèle, il faudrait ajouter un certain nombre de données, en particulier :

Seconde Partie

#include <stdio.h>
typedef struct brique
 {
   float x; float y; float z;
   float lx; float ly; float lz;
 }brique;
#define MAXI 100
typedef brique tableau[MAXI];

Question 2-1

void saisie(tableau t, int nb)
{
 int i;
 for(i=0;i<nb;i++)
 {
  printf("volume n° %d : entrez les 3 coordonnées du coin :");
  scanf("%f %f %f",&(t[i].x),&(t[i].y),&(t[i].z));
  printf("entrez les 3 longueurs:");
  scanf("%f %f %f",&(t[i].lx),&(t[i].ly),&(t[i].lz));
 }
 printf("merci\n");
}

Question 2-2

facile : mettre une * devant nb à chaque fois qu'il apparait et bien sûr commencer la fonction par demander sa valeur. dans main, il faut rajouter un & devant nb : saisie_bis(lego,&nb);
void saisie_bis(tableau t, int * nb)
{
 int i;
 printf("nombre de briques ?");
 scanf("%d",nb); // &*nb <=> nb
 for(i=0;i<*nb;i++)
 {
  printf("volume n° %d : entrez les 3 coordonnées du coin :");
  scanf("%f %f %f",&(t[i].x),&(t[i].y),&(t[i].z));
  printf("entrez les 3 longueurs:");
  scanf("%f %f %f",&(t[i].lx),&(t[i].ly),&(t[i].lz));
 }
 printf("merci\n");
}

Question 2-3

float volume(brique b)
{
 return(b.lx*b.ly*b.lz);
}
float volume_total(tableau t,int nb)
{
 int i;
 float v=0;
 for(i=0;i<nb;i++) v+=volume(t[i]);
 return(v);
}

Question 2-4

void recherche_CdG(tableau t, int nb)
{
 float xg=0,yg=0,zg=0,v;
 int i;
 for(i=0;i<nb;i++)
 {
  v=volume(t[i]); //pas la peine de le recalculer 3 fois
  xg+=(t[i].x+t[i].lx/2)*v;
  yg+=(t[i].y+t[i].ly/2)*v;
  zg+=(t[i].z+t[i].lz/2)*v;
 }
 v=volume_total(t,nb); //pas la peine de le recalculer 3 fois
 xg/=v;yg/=v;zg/=v;
 printf("centre de gravité : xg=%f,yg=%f,zg=%f\n",xg,yg,zg);
}

void main(void)
{
 tableau lego;
 int nb;
 printf("nombre de briques ?");
 scanf("%d",&nb);
 saisie(lego,nb);
 recherche_CdG(lego,nb);
}

/* sous Turbo C décommenter les lignes suivantes */
void PatchScanfPourFlottant(void)
{float x;scanf("",&x);}
 

Troisième Partie

#include <stdio.h>
#define MAX_PTS 100
int nb_pts;
float x[MAX_PTS],y[MAX_PTS];

Question 3-1

float signe_cote(int a,int b,int c)
{
 float val;
 val=((x[a]-x[c])*(y[b]-y[a]))
    -((y[a]-y[c])*(x[b]-x[a]));
 return(val);
}
//on aurait pu rendre simplement un entier :
// if(val>0)return(1);else return(-1);

Question 3-2

int est_frontiere(int a,int b)
{
 int i;
 float signe_premier;
 //tout d'abord, chercher le signe du premier
 if(a!=0&&b!=0)signe_premier=signe_cote(a,b,0);
 else if(a!=1&&b!=1)signe_premier=signe_cote(a,b,1);
 else signe_premier=signe_cote(a,b,2);
 //si on trouve un signe différent : abandonner
 for(i=1;i<nb_pts;i++)
   if(i!=a && i!=b) //inutile de tester A et B !!!
     if(signe_premier*signe_cote(a,b,i)<0) return(0);
 //si on n'est pas sorti avant, c'est qu'ils sont TOUS bons
 return(1);
}

Question 3.3

void bonus_un_pt(void)
{
 printf("j'ai lu le sujet jusqu'au bout\n");
}

//programme de test
void main(void)
{
 int i,a,b;
 printf("nb de pts ?");
 scanf("%d",&nb_pts);
 for(i=0;i<nb_pts;i++)
 {
  printf("coord X et Y du pt %d ? ",i);
  scanf("%f %f",x+i,y+i);
 }
 do
 {
  printf("donnez 2 numéros de pt (négatif pour arrêter) : ");
  scanf("%d %d",&a,&b);
  if(a<0||b<0)return;
  if(est_frontiere(a,b))printf("ils sont frontière\n");
    else printf("ils ne sont pas frontière\n");
 }while(1);
}
/* sous Turbo C décommentez les lignes suivantes */
void PatchScanfPourFlottant(void)
{float x;scanf("",&x);}

 


pour retourner au sujet (s'il n'est pas déja dans une autre fenêtre) , cliquez ici
pour retourner au sommaire des sujets d'examen, cliquez ici


Patrick TRAU, ULP - IPST mai 2000