Table des matières
Le problème est simple. Il s’agit de savoir quand les deux
Rivières digitales
1 vont se croiser.
Input | Output |
---|---|
long long r_1, long long r_2 | long long valeur de croisement |
r_1 et r_2 désignent les 2 rivières de départ.
On cherche donc à trouver la valeur de croisement. Pour celà, on prend la plus petite valeur des 2 rivières et on lui ajoute la somme de ses chiffres jusqu’à ce que les 2 rivières soit égales.
#include <stdio.h>
long long number_sum(long long number){
long sum = 0;
do {
+= number % 10;
sum /= 10;
number } while (number != 0);
return sum;
}
int main()
{
long long r_1;
("%lld", &r_1);
scanflong long r_2;
("%lld", &r_2);
scanfwhile( r_1 != r_2 ) {
if (r_1 < r_2){
+= number_sum(r_1);
r_1 } else{
+= number_sum(r_2);
r_2 }
}
("%lld\n", r_1);
printf
return 0;
}
Input | Output |
---|---|
long long number | long long sum |
On calcule la somme des chiffres de number
. Pour celà,
tant que number
ne vaut pas 0, on ajoute à
somme
le modulo en base 10 de number
et on
affecte à number
le quotient de sa division entière par
10.
On commence par récupérer les deux entiers r_1 et
r_2.
Tant que les entiers ne sont pas égaux, on cherche :
number_sum()
de lui-même.#include <stdio.h>
// --------------------------------------------
int s(int n) {
return n ? n % 10 + s( n / 10 ) : 0 ;
}
// --------------------------------------------
(r1, r2) {
mainif ( r1 == 1 ) scanf("%d %d", &r1, &r2);
if ( r1 == r2 ) printf("%d", r1);
if ( r1 > r2 ) main ( r1 , r2 + s(r2) );
if ( r1 < r2 ) main ( r1 + s(r1) , r2 );
}
Ce qui saute évidemment aux yeux c’est la beauté de la simplicité des solutions courtes et claires.
Cette fonction renvoie la somme des chiffres du nombre n donné.
On repère ici 2 astuces particulièrement intelligentes:
if (n){
return n%10 + s(n/10);
} else {
return 0;
}
Encore une fois, l’efficacité est saisissante ! Une nouvelle fois, main est une fonction récursive. Le cas de base de cette fonction est lorsque les deux rivières sont égales. Sinon, on rappelle la fonction main en changeant la de la plus petite rivière.
Ici le problème est un peu différent car il s’agit de déterminer si
il exister une Rivière n
différentes de K
tel que rivière n passe par K.
Cette fois-ci, on cherche à savoir si pour une rivière donnée, il existe plus d’une rivière qui la rencontre.
Input | Output |
---|---|
long long r_1 | “YES” | “NO” |
On parcours, chaque rivière de 1 à r_1 en marquant chaque valeur déjà rencontrée afin de n’y passer qu’une seule fois jusqu’à trouver ou non une rivière r_2 qui croise r_1.
#include <stdio.h>
long long number_sum(long long number){
long sum = 0;
do {
+= number % 10;
sum /= 10;
number } while (number != 0);
return sum;
}
int main()
{
long long r_1, r_2;
long long i;
("%d", &r_1);
scanfint visited_rivers[r_1];
for (i = 1; i <= r_1; i++){
[i] = i;
visited_rivers}
for (i = 1; i<r_1; i++){
= i;
r_2 while (visited_rivers[r_2] && r_2 <= r_1){
[r_2] = 0;
visited_riversif (r_2 == r_1){
("YES");
putsreturn 0;
}
+= number_sum(r_2);
r_2 }
}
("NO\n");
printf
return 0;
}
La fonction number_sum est la même que la précédente
Dans le détails; on initialise un tableau visited_rivers associant pour chaque i allant de 1 à r_1 pour marquer les rivières déjà visitées. Ensuite, on créé une rivière r_2 pour chaque valeur allant de 1 à r_1 :
visited_rivers[r_2]
)"YES"
et arrête le program si r_1
fini par valoir r_2Si l’on arrive a la fin du program, on fini par afficher
"NON"
.
#include <stdio.h>
// --------------------------------------------
int
(int n) {
sumreturn n ? n%10+sum(n/10) : 0 ;
}
// --------------------------------------------
#define N 100000
int sieve[N];
void
(void) {
sieveComputefor (int i = 1 ; i < N ; i++) {
for (int j = i ; sieve[j] == 0 && j < N ; j += sum(j)) {
[j] = i;
sieve}
}
}
// --------------------------------------------
int main() {
int r1;
("%d", &r1);
scanf();
sieveCompute( sieve[r1] == r1 ? "NO": "YES");
printf}
Je suis admiratif devant les solutions d’Alain-Delpuch qui font pour moi preuve d’une grande intelligence dans leur dévelopement. Il sait tirer pleinement partie de toutes les spécificités du C. J’aimerai pouvoir être capable de rédiger du code aussi propre.
Une rivière digitale (notée river n) est une suite tel que avec le nombre de chiffre de .↩︎