ค้นหาผลรวมลำดับที่ใหญ่ที่สุด


11

กำหนดลำดับของจำนวนเต็มหาผลรวมที่ใหญ่ที่สุดของลำดับ (จำนวนเต็มในตำแหน่งต่อเนื่อง) ของลำดับ การเรียงลำดับสามารถเป็นค่าว่างได้ (ในกรณีนี้ผลรวมคือ 0)

อินพุตถูกอ่านจากอินพุตมาตรฐานหนึ่งจำนวนเต็มหนึ่งต่อบรรทัด ผลรวมที่ใหญ่ที่สุดจะต้องเขียนลงในเอาต์พุตมาตรฐาน

ฉันเขียนเครื่องกำเนิดไฟฟ้าขนาดเล็กสำหรับคุณ:

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

ตัวอย่าง:

$ 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.out เป็นเครื่องกำเนิดไฟฟ้า

โซลูชันของคุณจะต้องทำงานในเวลาที่เหมาะสมสำหรับการทดสอบทั้งหมดข้างต้น (การทำงานของฉันใน 1.2s ในกรณีทดสอบสุดท้าย)

รหัสที่สั้นที่สุดชนะ

แก้ไข : โปรดระบุตัวอย่างการทดสอบข้อใดข้อหนึ่งข้างต้น


คุณจำเป็นสำหรับ#include <stdlib.h> atoi()
Paul R

โซลูชัน c ของฉันใช้เวลา 4 วินาทีสำหรับกรณีทดสอบครั้งล่าสุดสนใจมากเกี่ยวกับโซลูชันของคุณ
Dongshengcn

ตรวจสอบให้แน่ใจว่าคุณเขียนไฟล์เป็นอันดับแรกจากนั้นอ่านจากไฟล์และไม่ใช้ไพพ์
Alexandru

ฉันเดาว่ามีข้อผิดพลาดในเครื่องกำเนิดของคุณบรรทัดที่ 25 while (i--);ไม่ควรลงท้ายด้วยเครื่องหมายอัฒภาคใช่ไหม
ผู้ใช้ที่ไม่รู้จัก

assert (argc == 3) :-) นั่นคือสิ่งที่ฉันเรียกว่าโปรแกรมที่ใช้งานง่าย! :-)
Emanuel Landeholm

คำตอบ:


3

Ruby, 53 ตัวอักษร

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

ใช้เวลาประมาณ 28 วินาทีสำหรับการทดสอบครั้งสุดท้ายที่นี่


6

Python 91 84 64 ตัวอักษร

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

ใช้เวลาประมาณ14 12 72 วินาทีในกรณีทดสอบล่าสุด แก้ไข: พบอัลกอริทึมโดย Paul R แก้ไข: input()ขีดนำเข้าที่ใช้


6

C, 100 ตัวอักษร


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


เวลารัน = 1.14 วินาทีสำหรับกรณีทดสอบขั้นสุดท้าย (10,000000) บน 2.67 GHz Core i7 พร้อม ICC 11.1 (ก่อนหน้านี้: 1.44 วิด้วย gcc 4.2.1)

หมายเหตุ: อัลกอริทึมที่ใช้สำหรับการแก้ปัญหาข้างต้นมาจากการเขียนโปรแกรม Pearlsโดย Jon Bentley เห็นได้ชัดว่าขั้นตอนวิธีนี้เป็นที่รู้จักกันKadane ของอัลกอริทึม


3

Haskell ( 88 64)

การใช้อัลกอริทึมของ Kadane

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

2

Python - 114 ตัวอักษร

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:])`

แน่นอนว่ามันไม่เร็วอย่างที่ต้องการ แต่ก็ใช้ได้ดี


นี่คือ O (N ^ 2) ซึ่งไม่ตรงตามข้อกำหนดของการท้าทาย
Alexandru

2

Python โดยใช้การเขียนโปรแกรมแบบไดนามิก - 92 ตัวอักษร

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 ตัวอักษร)

โซลูชันนี้ใช้อัลกอริทึมของ Kadane แตกต่างกันและรวดเร็วพอสมควร

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

นี่คือคำอธิบาย:

  • u/ y- คำกริยาu แทรกyระหว่างรายการ เช่น+/ 1 2 3 4เป็นเช่น1 + 2 + 3 + 4นั้น ขอให้สังเกตว่าคำกริยาทั้งหมดในเจมีสิทธิที่เกี่ยวข้องที่เป็น-/ 1 2 3 4เหมือนและคำนวณผลรวมสลับ1 - (2 - (3 - 4))1 2 3 4
  • x >. y- สูงสุดของและxy
  • x ([ >. +) y- สูงสุดของและx เป็นคำกริยาในสัญกรณ์โดยปริยายและประเมินผลจะเป็นเช่นเดียวกับx + y[ >. +x >. x + y
  • ([ >. +)/ y- คำนำหน้าไม่ว่างของyด้วยผลรวมที่ใหญ่ที่สุด
  • u\. y- นำไปใช้ต่อท้ายทั้งหมดของu yขอให้สังเกตว่ารหัสพิเศษจัดการกับกรณีทั่วไปu/\. yเช่นนี้ทำงานในเชิงเส้นแทนเวลากำลังสอง
  • ([ >. +)/\. y- เวกเตอร์ denoting subarray yไม่ว่างเปล่าที่ใหญ่ที่สุดที่เริ่มต้นที่ตำแหน่งของแต่ละ
  • 0 , ([ >. +)/\. y- 0preprended เพื่อผลก่อนเนื่องจาก0เป็นความยาวของ subarray yว่างของ
  • >./ 0 , ([ >. +)/\. y- เดอะ subarray yที่ใหญ่ที่สุดของ
  • 0 ". ];._2 (1!:1) 3 - อินพุตมาตรฐานจะถูกแยกเป็นเวกเตอร์ของตัวเลข
  • >./ 0 , ([ >. +)/\. 0 ". ];._2 (1!:1) 3 - subarray ที่ใหญ่ที่สุดในอินพุตมาตรฐาน

1

ทับทิม 68 ตัวอักษร

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-10000000 ในอีกครึ่งนาทีส่วนใหญ่เวลาที่ใช้ในการทดสอบครั้งสุดท้าย ...

รุ่นที่เยื้อง:

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 ตัวอักษร

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

ทำงานได้รวดเร็วพอสมควรบนแล็ปท็อปของฉัน (4 วินาทีสำหรับการทดสอบครั้งสุดท้าย)


cstdlibไม่ใช่stdlib.h
oldrinb

1
{if((r+$1)>0)
   r=r+$1 
 else r=0; 
 if(m<r) 
   m=r;
}
END{print m}

รหัส awk (66) , ช้ามาก, 8+ วินาทีสำหรับการทดสอบครั้งสุดท้าย

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

real    0m6.705s
user    0m8.671s
sys 0m0.052s
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.