Dada uma sequência de números inteiros, encontre a maior soma de uma subsequência (números inteiros em posições consecutivas) da sequência. A subsequência pode estar vazia (nesse caso, a soma é 0).
A entrada é lida a partir da entrada padrão, um número inteiro por linha. A maior soma deve ser gravada na saída padrão.
Eu escrevi um pequeno gerador para você:
#include <stdio.h>
#include <assert.h>
/* From http://en.wikipedia.org/wiki/Random_number_generation */
unsigned m_w;
unsigned m_z;
unsigned get_random()
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; /* 32-bit result */
}
int main(int argc, char **argv)
{
int i;
assert(argc == 3);
m_w = atoi(argv[1]);
m_z = atoi(argv[2]);
i = 10;
while (i--);
get_random();
i = atoi(argv[2]);
while (i--)
printf("%d\n", (int) get_random() << 8 >> 22);
return 0;
}
Exemplos:
$ printf "1\n2\n-1\n4\n" | ./sum
6
$ printf "0\n-2\n-3\n" | ./sum
0
$ ./a.out 1 1 | ./sum
387
$ ./a.out 1 10 | ./sum
571
$ ./a.out 1 100 | ./sum
5867
$ ./a.out 1 1000 | ./sum
7531
$ ./a.out 1 10000 | ./sum
27268
$ ./a.out 1 100000 | ./sum
101332
$ ./a.out 1 1000000 | ./sum
187480
$ ./a.out 1 10000000 | ./sum
666307
./sum
é a minha solução./a.out
é o gerador
Sua solução deve ser executada em tempo razoável para todos os testes acima (o meu é executado em 1,2s no último caso de teste).
O menor código vence.
Editar : forneça um exemplo executado em um dos testes acima.
code-golf
subsequence
Alexandru
fonte
fonte
#include <stdlib.h>
paraatoi()
.while (i--);
não deve terminar em ponto e vírgula, não é?Respostas:
Ruby, 53 caracteres
Leva cerca de 28 segundos para o último caso de teste aqui.
fonte
Python,
918464 caracteresLeva cerca de
141272 segundos no último caso de teste. Edit: usando o algoritmo que Paul R encontrou. Editar: nixou a importação, usandoinput()
.fonte
C, 100 caracteres
Tempo de execução = 1,14 s para o caso de teste final (10000000) no Core i7 de 2,67 GHz com ICC 11.1 (anteriormente: 1,44 s com gcc 4.2.1).
Nota: O algoritmo usado para a solução acima vem de Programming Pearls, de Jon Bentley. Aparentemente, esse algoritmo é conhecido como algoritmo de Kadane .
fonte
Haskell (
8864)Implementando o algoritmo de Kadane.
fonte
Python - 114 caracteres
Certamente não é tão rápido quanto necessário, mas funciona bem.
fonte
Python, usando programação dinâmica - 92 caracteres
fonte
J (
3433 caracteres)Esta solução implementa uma variante do algoritmo de Kadane e é razoavelmente rápida.
Aqui está uma explicação:
u/ y
- O verbou
inserido entre os itens dey
. Por exemplo,+/ 1 2 3 4
é como1 + 2 + 3 + 4
. Observe que todos os verbos em J estão associados à direita, ou seja,-/ 1 2 3 4
são semelhantes1 - (2 - (3 - 4))
e calculam a soma alternada de1 2 3 4
.x >. y
- o máximo dex
ey
.x ([ >. +) y
- O máximo dex
ex + y
.[ >. +
é um verbo em notação tácita e é avaliado da mesma forma quex >. x + y
.([ >. +)/ y
- o prefixo não vazio dey
com a maior soma.u\. y
-u
aplicado a todos os sufixos dey
. Observe que o código especial lida com o caso comum, deu/\. y
modo que seja executado em tempo linear e não quadrático.([ >. +)/\. y
- Um vetor que denota o maior subarray não vazio que inicia em cada posição dey
.0 , ([ >. +)/\. y
-0
pré-previsto para o resultado anterior, assim como0
o comprimento de um subarray vazio dey
.>./ 0 , ([ >. +)/\. y
- O maior sub-arranjo dey
.0 ". ];._2 (1!:1) 3
- Entrada padrão empacotada em um vetor de números.>./ 0 , ([ >. +)/\. 0 ". ];._2 (1!:1) 3
- O maior subarray da entrada padrão.fonte
Ruby, 68 caracteres
Também um pouco lento, mas conclui os testes 1-10000000 em pouco mais de meio minuto, a maior parte do tempo gasto no último teste ...
Versão recuada:
fonte
C ++, 192 caracteres
Funciona razoavelmente rápido no meu laptop (4 segundos para o último teste).
fonte
cstdlib
nãostdlib.h
Código awk (66) , muito lento, mais de 8 segundos para o último caso de teste
fonte