Jean-Jacques Lévy Yves Robert
20 décembre 2000 -- 2h
Avertissement On attachera une grande importance
à la clarté, à la précision, à la concision de la
rédaction. Les sections A et B sont indépendantes.
A. Décompositions d'entiers
Soit n ³ 0 un entier fixé. Une décomposition de n est un
k-uplet d'entiers (a1, a2, ..., ak) tel que ai ³ 1
pour 1 £ i £ k et a1 + a2 + ... + ak = n. On ordonne
les décompositions additives de n par l'ordre lexicographique. Par
exemple si n = 10,
(2,5,1,1,1) < (2,5,2,1) < (3,7) < (4,1,1,1,1,2).
Formellement, l'ordre lexicographique (l'ordre du dictionnaire) est
défini de la manière suivante: (a1, a2, ... ak) < (b1, b2,
... b) ssi ai = bi pour 1 £ i £ m pour un m tel
que 0 £ m £ k et soit m = k < , soit am+1 < bm+1.
Noter que cet ordre est total.
On représente les décompositions sous forme de listes chaînées
contenant successivement les valeurs a1, a2, ..., ak.
Question 1Préciser la structure de donnée sous forme d'une classe ListeDecomp en Java. Ecrire une fonction static boolean
estDecomp(ListeDecomp d, int n) qui vérifie si la liste d
représente bien une décomposition de n.
Question 2Donner toutes les décompositions du nombre 5 dans l'ordre
lexicographique. Combien de chiffres sont modifiés dans une
décomposition pour obtenir la suivante?
Question 3Ecrire la fonction static boolean estMax(ListeDecomp d,
int n) qui vérifie si une liste d est une décomposition de n sans
successeur dans l'ordre lexicographique.
Question 4Etant donnée une décomposition d de n qui n'est pas la
plus grande, écrire la fonction static ListeDecomp
suivante(ListeDecomp d) qui renvoie la décomposition suivante de
d (dans l'ordre lexicographique).
B. Partage équilibré de périmètre
Soit un polygone dont la suite des longueurs des côtés á a0,
a1, a2, ..., an-1 ñ est stockée dans un tableau
unidimensionnel d'entiers de taille n ³ 2. Soit une paire
d'indices (i,j), avec 0 £ i < n et 0 £ j < n; ces indices
déterminent deux portions de périmètres, l'une de longueur
åk=ij-1 ak et l'autre de longueur åk=ji-1 ak,
où tous les indices sont pris modulo n. On cherche la (en fait,
une) paire d'indices qui minimise la valeur absolue de la différence
des deux portions de périmètre qu'ils déterminent, i.e.
|
|
D(i,j) avec D(i,j)
= |
½ ½ ½ ½ |
|
|
ak - |
|
ak |
½ ½ ½ ½ |
Le polygone est représenté par un tableau int[ ] a donnant les
longueurs de tous ses cotés.
Nous allons construire des solutions de plus en plus efficaces. Le
coût d'une solution est défini comme le nombre d'opérations
élémentaires (addition d'entiers, accès à un tableau, etc) qu'elle
effectue. (Rappel: en Java, l'expression x modulo n s'écrit x % n.)
Question 5Quel serait l'ordre de grandeur O(nx) du coût de la
méthode suivante, trop naïve pour que nous l'écrivions en Java: pour
toutes les paires (i,j), calculer la différence D(i,j) et
prendre le minimum?
Question 6Ecrire une fonction static int perimetre(int[] a) qui
renvoie le périmètre total du polygone décrit par a.
Question 7Pour un indice i donné, soit d(i) le premier indice
tel que åk=id(i) ak > p/2, où p est le périmètre (et les
indices sont toujours pris modulo n).
a) Montrer que l'indice j tel que D(i, j) =
min 0 £ j < n D(i,j) est égal soit à d(i) soit à
d(i)+1.
b) Ecrire une fonction static void partage1(int[] a)
qui calcule et imprime la solution optimale (i,j,D(i,j)). On
veut que le coût de la fonction partage1(a) soit en O(n2).
Question 8On demande maintenant d'écrire une fonction static void
partage2(int[] a) similaire à la fonction précédente mais dont le
coût est en O(n), i.e. linéaire en n. Il est impératif de
justifier le principe de votre algorithme avant d'écrire la fonction.
This document was translated from LATEX by HEVEA.