Ecrivez un programme (ou une fonction) qui présente quatre grandes complexités de temps O communes, en fonction de la manière dont il est exécuté. Quelle que soit sa forme, il prend un entier positif N que vous pouvez supposer inférieur à 2 31 .
Lorsque le programme est exécuté dans sa forme d' origine, sa complexité doit être constante . C'est-à-dire que la complexité devrait être (1) ou, de manière équivalente, (1 ^ N) .
Lorsque le programme est inversé et exécuté, il doit avoir une complexité linéaire . C'est-à-dire que la complexité devrait être (N) ou, de manière équivalente, Θ (N ^ 1) .
(Cela a du sens puisqueN^1
est1^N
inversé.)Lorsque le programme est doublé , ce concaténé à lui - même, et l' exécuter devrait avoir exponentielle la complexité, en particulier 2 N . C'est-à-dire que la complexité devrait être (2 ^ N) .
(Cela a du sens puisque l'2
in2^N
est le double de l'1
in1^N
.)Lorsque le programme est doublé , inversé et exécuté, il doit présenter une complexité polynomiale , en particulier N 2 . C'est-à-dire que la complexité devrait être (N ^ 2) .
(Cela a du sens puisqueN^2
est2^N
inversé.)
Ces quatre cas sont les seuls dont vous avez besoin.
Notez que pour plus de précision, j'utilise la notation thêta grosse () au lieu de la lettre grand O car les exécutions de vos programmes doivent être limitées à la fois par le haut et par le bas par la complexité requise. Sinon, écrire une fonction dans O (1) satisferait les quatre points. Il n’est pas très important de comprendre la nuance ici. Principalement, si votre programme effectue des opérations k * f (N) pour une constante k alors il est probable qu'il se trouve dans Θ (f (N)).
Exemple
Si le programme initial était
ABCDE
puis cela devrait prendre un temps constant. En d'autres termes, que l'entrée N soit égale à 1 ou 2147483647 (2 31 -1) ou à une valeur quelconque, elle doit se terminer à peu près dans le même temps.
La version inversée du programme
EDCBA
devrait prendre un temps linéaire en termes de N. Autrement dit, le temps nécessaire pour terminer doit être approximativement proportionnel à N. Donc, N = 1 prend le moins de temps et N = 2147483647, le plus.
La version doublée du programme
ABCDEABCDE
devrait prendre le temps de deux à la N en termes de N. C'est, le temps qu'il faut mettre fin devrait être à peu près proportionnelle à 2 N . Donc, si N = 1 se termine dans environ une seconde, N = 60 prendra plus de temps que l'âge de l'univers pour se terminer. (Non, vous n'avez pas à le tester.)
La version doublée et inversée du programme
EDCBAEDCBA
devrait prendre un temps carré en termes de N. Autrement dit, le temps nécessaire pour terminer doit être à peu près proportionnel à N * N. Donc, si N = 1 se termine dans environ une seconde, N = 60 prend environ une heure pour se terminer.
Détails
Vous devez montrer ou argumenter que vos programmes fonctionnent dans les complexités que vous dites être. Donner des données temporelles est une bonne idée, mais essayez également d’expliquer pourquoi la complexité est théoriquement correcte.
C'est bien si, en pratique, les temps que prennent vos programmes ne sont pas parfaitement représentatifs de leur complexité (ou même déterministes). Par exemple, l'entrée N + 1 peut parfois courir plus vite que N.
L'environnement dans lequel vous exécutez vos programmes est important. Vous pouvez faire des suppositions de base sur le fait que les langages populaires ne perdent jamais intentionnellement du temps dans des algorithmes. Par exemple, si vous savez que votre version de Java implémente le tri à bulle au lieu d'un algorithme de tri plus rapide , vous devez en tenir compte si vous effectuez un tri. .
Pour toutes les complexités, supposons ici que nous parlons des pires scénarios , et non des cas optimaux ou moyens.
La complexité spatiale des programmes n'a pas d'importance, seule la complexité temporelle.
Les programmes peuvent sortir n'importe quoi. Il importe seulement qu’ils prennent le nombre entier positif N et aient les complexités temporelles correctes.
Les commentaires et les programmes multilignes sont autorisés. (Vous pouvez supposer que la compatibilité avec Windows
\r\n
est inversée\r\n
.)
Big O Rappels
Du plus rapide au plus lent O(1), O(N), O(N^2), O(2^N)
(ordre 1, 2, 4, 3 ci-dessus).
Les termes les plus lents dominent toujours, par exemple O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
pour constante k. Alors O(2) = O(30) = O(1)
et O(2*N) = O(0.1*N) = O(N)
.
Rappelez O(N^2) != O(N^3)
- vous et O(2^N) != O(3^N)
.
Notation
C'est un code de golf normal. Le programme original le plus court (le temps constant un) en octets l'emporte.
n = input(); for i in xrange(n): pass
a une complexité exponentielle, car il prend des 2 ** k
étapes, où k = log_2(n)
est la taille d'entrée. Vous devez préciser si c'est le cas, car cela change radicalement les exigences.