Temukan penjumlahan terbesar

11

Diberikan urutan bilangan bulat menemukan jumlah terbesar dari urutan (bilangan bulat pada posisi berurutan) dari urutan. Urutan selanjutnya bisa kosong (dalam hal ini jumlahnya adalah 0).

Input dibaca dari input standar, satu bilangan bulat per baris. Jumlah terbesar harus ditulis ke output standar.

Saya menulis generator kecil untuk Anda:

#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;
}

Contoh:

$ 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 adalah solusi saya
  • ./a.out adalah generatornya

Solusi Anda harus berjalan dalam waktu yang wajar untuk semua tes di atas (milik saya berjalan di 1.2s pada kasus tes terakhir).

Kode terpendek menang.

Sunting : Berikan contoh yang dijalankan pada salah satu tes di atas.

Alexandru
sumber
Anda perlu #include <stdlib.h>untuk atoi().
Paul R
Solusi c saya sendiri membutuhkan waktu 4 detik untuk test case terakhir, sangat tertarik dengan solusi Anda.
Dongshengcn
Pastikan Anda menulis pertama ke file dan kemudian membaca dari file, dan tidak menggunakan pipa.
Alexandru
Saya kira ada kesalahan pada generator Anda, baris 25, while (i--);tidak seharusnya diakhiri dengan tanda titik koma, bukan?
pengguna tidak dikenal
menegaskan (argc == 3) :-) Itulah yang saya sebut program ramah pengguna! :-)
Emanuel Landeholm

Jawaban:

3

Ruby, 53 karakter

p$<.inject(-1.0/s=0){|a,b|[s=[0,s+b.to_i].max,a].max}

Butuh waktu sekitar 28 detik untuk testcase terakhir di sini.

Ventero
sumber
6

Python, 91 84 64 karakter

s=m=0
try:
 while 1:s=max(s+input(),0);m=max(m,s)
except:print m

Memakan waktu sekitar 14 12 72 detik pada test case terakhir. Sunting: menggunakan algoritma yang ditemukan Paul R. Sunting: mem-nix impor, menggunakan input().

stan
sumber
6

C, 100 karakter


main(){char s[80];int i,m=0,n=0;while(gets(s)){i=atoi(s);n=n+i>0?n+i:0;m=m>n?m:n;}printf("%d\n",m);}


Jalankan waktu = 1,14 dtk untuk test case akhir (10000000) pada 2,67 GHz Core i7 dengan ICC 11.1 (sebelumnya: 1,44 dtk dengan gcc 4.2.1).

Catatan: Algoritma yang digunakan untuk solusi di atas berasal dari Pemrograman Mutiara oleh Jon Bentley. Tampaknya algoritma ini dikenal sebagai Algoritma Kadane .

Paul R
sumber
3

Haskell ( 88 64)

Menerapkan algoritma Kadane.

main=interact$show.maximum.scanr(\x->max x.(x+))0.map read.lines
FUZxxl
sumber
2

Python - 114 karakter

import sys
s=map(int,sys.stdin.readlines())
l=range(len(s)+1)
print`max(sum(s[i:j])for i in l[:-1]for j in l[i:])`

Ini tentu saja tidak secepat yang diminta, tetapi bekerja dengan baik.

Juan
sumber
Ini adalah O (N ^ 2) yang tentu saja tidak memenuhi persyaratan tantangan.
Alexandru
2

Python, menggunakan pemrograman dinamis - 92 karakter

import sys
s=map(int,sys.stdin.readlines())
f=h=0
for x in s:h=max(0,h+x);f=max(f,h)
print f
BiGeek
sumber
2

J ( 34 33 karakter)

Solusi ini mengimplementasikan varian dari algoritma Kadane dan cepat masuk akal.

echo>./0,([>.+)/\.0".];._2(1!:1)3

Berikut ini penjelasannya:

  • u/ y- Kata kerja u disisipkan di antara item dari y. Misalnya, +/ 1 2 3 4seperti 1 + 2 + 3 + 4. Perhatikan bahwa semua kata kerja dalam J terkait-benar, yaitu, -/ 1 2 3 4seperti 1 - (2 - (3 - 4))dan menghitung jumlah bolak-balik dari 1 2 3 4.
  • x >. y- maksimum xdan y.
  • x ([ >. +) y- Maksimal dari xdan x + y. [ >. +adalah kata kerja dalam notasi diam-diam dan dievaluasi sama dengan x >. x + y.
  • ([ >. +)/ y- awalan non-kosong ydengan jumlah terbesar.
  • u\. y- uditerapkan untuk semua sufiks y. Perhatikan bahwa kode khusus menangani kasus umum u/\. ysehingga ini berjalan secara linier, bukan waktu kuadratik.
  • ([ >. +)/\. y- Vektor yang menunjukkan subarray non-kosong terbesar yang dimulai pada setiap posisi y.
  • 0 , ([ >. +)/\. y- 0Dipersiapkan untuk hasil sebelumnya seperti 0panjang subarray kosong y.
  • >./ 0 , ([ >. +)/\. y- Subarray terbesar dari y.
  • 0 ". ];._2 (1!:1) 3 - Input standar disusun menjadi vektor angka.
  • >./ 0 , ([ >. +)/\. 0 ". ];._2 (1!:1) 3 - Subarray terbesar dalam input standar.
FUZxxl
sumber
1

Ruby, 68 karakter

m=-2**31;n=0;$<.lines.map{|x|n+=x.to_i;n=0 if n<0;m=n if n>m};puts m

Juga agak lambat, tetapi menyelesaikan tes 1-10000000 dalam sedikit lebih dari setengah menit, sebagian besar waktu dihabiskan di tes terakhir ...

Versi indentasi:

m=-2**31
n=0
$<.lines.map {|x|
  n+=x.to_i
  n=0 if n<0
  m=n if n>m
}
puts m
Joaquim Rendeiro
sumber
1

C ++, 192 karakter

#include <iostream>
#include <string>
#include <stdlib.h>
#define S std::
main(){long a=0,m=0,M=0;char s[9];while(S cin.getline(s,9)){a+=atoi(s);if(m>a)m=a;if(M<a-m)M=a-m;}S cout<<M<<S endl;}

Bekerja cukup cepat di laptop saya (4 detik untuk tes terakhir).

Benoit
sumber
cstdlibnotstdlib.h
oldrinb
1
{if((r+$1)>0)
   r=r+$1 
 else r=0; 
 if(m<r) 
   m=r;
}
END{print m}

Kode awk (66) , sangat lambat, 8+ detik untuk test case terakhir

dwang@dwang-ws ~/Playground/lss $ time ./random 1 10000000 | awk -f lss.awk
666307

real    0m6.705s
user    0m8.671s
sys 0m0.052s
Dongshengcn
sumber