Escreva um programa (ou função) que exiba quatro complexidades comuns de tempo grande, dependendo de como é executado. De qualquer forma, ele recebe um número inteiro positivo N, que você pode assumir que seja menor que 2 31 .
Quando o programa é executado em sua forma original , ele deve ter complexidade constante . Ou seja, a complexidade deve ser Θ (1) ou, equivalentemente, Θ (1 ^ N) .
Quando o programa é revertido e executado, ele deve ter complexidade linear . Ou seja, a complexidade deve ser Θ (N) ou, equivalentemente, Θ (N ^ 1) .
(Isso faz sentido, poisN^1
é1^N
revertido.)Quando o programa é duplicada , isto é concatenado a si mesma, e executá-lo deverá ter exponencial complexidade, especificamente 2 N . Ou seja, a complexidade deve ser Θ (2 ^ N) .
(Isso faz sentido, pois o2
in2^N
é o dobro do1
in1^N
.)Quando o programa é dobrado e invertida e executá-lo deverá ter polinomial complexidade, especificamente N 2 . Ou seja, a complexidade deve ser Θ (N ^ 2) .
(Isso faz sentido, poisN^2
é2^N
revertido.)
Esses quatro casos são os únicos com os quais você precisa lidar.
Observe que, para maior precisão, estou usando a notação teta grande (Θ) em vez de O grande, porque os tempos de execução dos seus programas devem ser limitados acima e abaixo pelas complexidades necessárias. Caso contrário, apenas escrever uma função em O (1) satisfaria todos os quatro pontos. Não é muito importante entender as nuances aqui. Principalmente, se o seu programa estiver executando operações k * f (N) por alguma constante k, é provável que esteja em Θ (f (N)).
Exemplo
Se o programa original fosse
ABCDE
então executá-lo deve levar tempo constante. Ou seja, se a entrada N é 1 ou 2147483647 (2 31 -1) ou qualquer valor intermediário, ela deve terminar aproximadamente na mesma quantidade de tempo.
A versão invertida do programa
EDCBA
deve levar um tempo linear em termos de N. Ou seja, o tempo necessário para terminar deve ser aproximadamente proporcional a N. Portanto, N = 1 leva menos tempo e N = 2147483647 leva mais.
A versão duplicada do programa
ABCDEABCDE
deve ter tempo two-to-the-N em termos de N. Ou seja, o tempo que leva para terminar deve ser aproximadamente proporcional a 2 N . Portanto, se N = 1 termina em cerca de um segundo, N = 60 levaria mais tempo que a idade do universo para terminar. (Não, você não precisa testá-lo.)
A versão duplicada e invertida do programa
EDCBAEDCBA
deve levar um tempo ao quadrado em termos de N. Ou seja, o tempo que leva para terminar deve ser aproximadamente proporcional a N * N. Portanto, se N = 1 termina em cerca de um segundo, N = 60 levaria cerca de uma hora para terminar.
Detalhes
Você precisa mostrar ou argumentar que seus programas estão sendo executados nas complexidades que você diz que são. Fornecer alguns dados de temporização é uma boa ideia, mas também tente explicar por que teoricamente a complexidade está correta.
Tudo bem se, na prática, o tempo gasto pelos seus programas não for perfeitamente representativo de sua complexidade (ou mesmo determinística). por exemplo, a entrada N + 1 às vezes pode ser mais rápida que N.
O ambiente em que você está executando seus programas é importante. Você pode fazer suposições básicas sobre como as linguagens populares nunca perdem tempo intencionalmente em algoritmos, mas, por exemplo, se você conhece sua versão específica do Java implementa a classificação por bolhas em vez de um algoritmo de classificação mais rápido , leve isso em consideração se fizer alguma classificação .
Para todas as complexidades aqui, assuma que estamos falando de cenários de pior caso , não de melhor ou médio.
A complexidade do espaço dos programas não importa, apenas a complexidade do tempo.
Os programas podem produzir qualquer coisa. É importante que eles recebam o número inteiro positivo N e tenham as complexidades de tempo corretas.
Comentários e programas multilinhas são permitidos. (Você pode assumir que o
\r\n
reverso é\r\n
para compatibilidade com o Windows.)
Big O Reminders
Do mais rápido para o mais lento O(1), O(N), O(N^2), O(2^N)
(peça 1, 2, 4, 3 acima).
Termos mais lentos sempre dominam, por exemplo O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
para constante k. Então O(2) = O(30) = O(1)
e O(2*N) = O(0.1*N) = O(N)
.
Lembre-se O(N^2) != O(N^3)
e O(2^N) != O(3^N)
.
Pontuação
Este é o código normal de golfe. O programa original mais curto (o tempo constante) em bytes vence.
n = input(); for i in xrange(n): pass
tem complexidade exponencial, porque executa 2 ** k
etapas, onde k = log_2(n)
está o tamanho da entrada. Você deve esclarecer se esse é o caso, pois altera drasticamente os requisitos.