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.


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.


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().


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 .


3

Haskell ( 88 64)

Menerapkan algoritma Kadane.

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

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.


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

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.

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

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).


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.