หัวหน้าที่จอดรถ


13

บทนำ

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

มันเป็นปัญหาที่ง่ายและปรับเปลี่ยนได้ในระดับสูงสุดของPATเมื่อปีที่แล้ว

ท้าทาย

คุณจะถูกถามในการคำนวณวิธีการหลายคันอยู่ในจำนวนมากในเวลาเดียวกันที่มากที่สุด

ใช้กฎมาตรฐาน และนี่คือรหัสกอล์ฟที่สั้นที่สุดที่จะชนะ

บรรทัดแรกคือปริมาณของรายการ (ไม่เกิน100,000, การป้อนข้อมูลของคุณอาจไม่ประกอบด้วยบรรทัดนี้หากคุณต้องการให้มันเป็นเพียงชั่วคราวเพื่อตรวจสอบการป้อนข้อมูลที่ปลาย ) ข้อความต่อไปนี้มีหนึ่งรายการต่อบรรทัด และแต่ละรายการมีสามตัวเลข:

<Car plate number> <Time (seconds) since open> <0(In) | 1(Out)>

การดัดแปลง 2:มันเป็นเรื่องปกติที่จะใช้อาร์เรย์ของอเนกประสงค์เป็นอินพุต

การดัดแปลง 3:คุณสามารถเปลี่ยนลำดับของตัวเลขในหนึ่งรายการ และคุณสามารถเลือกที่จะใช้ (ดูหัวข้อข้อสังเกต)

อินพุตรับประกันว่าถูกต้องสมมติว่า:

  • Car plate numberเป็นจำนวนเต็มในช่วง10000~99999
  • Timeเป็นจำนวนเต็มในช่วง0~86400

และ

  • คอมเมนต์ไม่จำเป็นต้องเรียงตามลำดับเวลา
  • ไม่มีรถก่อนวินาทีแรก
  • นอกจากนี้ไม่จำเป็นต้องไม่มีรถหลังจากวินาทีสุดท้าย
  • รถจะไม่ออกก่อนที่จะเข้า
  • Car plate numberมีเอกลักษณ์ (แต่รถคันเดียวกันสามารถเยี่ยมชมมากกว่าหนึ่งครั้ง)
  • ดังนั้นจึงเป็นไปไม่ได้ที่รถยนต์จะเข้ามาในล็อตเตอรี่เมื่อมันอยู่ในนั้น
  • timeรถเดียวกันจะไม่ไปในและนอกที่เดียวกัน
  • รถจะถือว่าเป็นจำนวนมากในเวลาที่เข้า / ออก

ตัวอย่างที่ 1

อินพุต

11
97845 36000 1
75487 16500 1
12345 16 0
75486 3300 0
12345 6500 1
97845 32800 0
12345 16400 0
97846 16501 1
97846 16500 0
75486 8800 1
75487 3300 0

เอาท์พุต

3

คำอธิบาย

ที่16500รถยนต์12345และ75487อยู่ในที่จอดรถ

ตัวอย่างที่ 2

ฉันทำสิ่งนี้เพราะฉันพบรหัสจำนวนมากล้มเหลว

อินพุต (โดยเว้นบรรทัดแรกออก)

12345 16400 0
12345 16500 1
75487 16500 0
75487 16600 1

เอาท์พุต

2

คำอธิบาย

ที่16500รถยนต์12345และ75487อยู่ในที่จอดรถ

หมายเหตุ

ที่จริงแล้วไม่จำเป็นต้องใช้ทั้งสามตัวสำหรับเอาต์พุต อย่างน้อยคุณจะต้องใช้แผ่น + เวลาหรือเวลาเข้า / ออกเท่านั้น แต่อัลกอริทึมนั้นแตกต่างกันเล็กน้อยภายใต้สถานการณ์สองสถานการณ์ดังนั้นการเลือกที่จะอยู่แบบสั้นนั้นไม่เป็นที่รู้จักในบางภาษา และแน่นอนคุณสามารถใช้ตัวเลขทั้งสามนี้ได้ ดังนั้นฉันจึงทิ้งพวกเขาไว้ในการท้าทาย


หมายเลขทะเบียนรถยาว 5 หลักเสมอหรือไม่
ติตัส

1
@Titus ฉันเชื่อว่าตัวเลขจาก 10,000 ถึง 99999 นั้นยาว 5 หลักเสมอ
Keyu Gan

3
ฉันเป็นคนตาบอดในวันนี้
ติตัส

ฉันคิดว่ารถไม่สามารถเข้าได้อีกก่อนออกจากครั้งแรกใช่ไหม ดูเหมือนว่าจะไม่ได้ระบุไว้อย่างชัดเจน
John Dvorak

@JanDvorak เอ๊ะขอโทษ ไม่สามารถทำได้ มันบอกเป็นนัย ๆ ว่าหมายเลขทะเบียนรถนั้นไม่เหมือนใครเพราะในความเป็นจริงมันเป็นไปไม่ได้ที่รถคันเดียวกันจะเข้ามาในล็อตเมื่อมันมีอยู่แล้ว
Keyu Gan

คำตอบ:


7

Mathematica, 33 ไบต์

-Min@Accumulate[2#2-1&@@@Sort@#]&

ฉันต้องอ่านคำแถลงปัญหาเพื่อทราบว่ามีอัลกอริทึมที่ง่ายกว่ามากซึ่งไม่ต้องการข้อมูลป้ายทะเบียนรถยนต์

ฟังก์ชันที่ไม่มีชื่อจะส่งคืนจำนวนเต็ม {time, 0|1, license plate}รูปแบบการป้อนข้อมูลที่เป็นรายการของอเนกประสงค์สั่งซื้อในแบบฟอร์ม เราเริ่มต้นด้วยSortไอเอ็นจีซึ่งทำให้รายการตามลำดับเหตุการณ์และยังแบ่งเวลาสัมพันธ์โดยการเรียงลำดับ0s ก่อน1s; จากนั้น2#2-1&@@@เก็บข้อมูลการมาถึง / ออกและลืมส่วนที่เหลือและแปลง0s เป็น-1s

Accumulateคำนวณผลรวมสะสมของรายการนั้น ผลที่ได้คือรายการที่เชิงลบของตัวเลขของรถยนต์ในลานจอดรถทุกครั้งหลังจากการมาถึง / ออกเดินทาง จากนั้นMinเลือกสิ่งที่เล็กที่สุด (ลบมากที่สุด) ของสิ่งเหล่านี้และลบเครื่องหมายลบ

Mathematica, 56 ไบต์

Max[<|#|>~Count~0&/@FoldList[List,{},#3->#2&@@@Sort@#]]&

การส่งดั้งเดิม (ความคิดเห็นหลายครั้งแรกอ้างถึงการส่งนี้) ฟังก์ชันที่ไม่มีชื่อจะส่งคืนจำนวนเต็ม {time, 0|1, license plate}รูปแบบการป้อนข้อมูลที่เป็นรายการของอเนกประสงค์สั่งซื้อในแบบฟอร์ม

เหตุผลที่เราเลือกที่จะใส่รายการเวลาก่อนและรายการเข้า / ออกที่สองคือการSort@#เรียงลำดับรายการตามลำดับเวลาและบันทึกการมาถึงก่อนออกเดินทางหากพวกเขาพร้อมกัน หลังจากนั้น#3->#2&@@@ส่งคืนรายการ "กฎ" ของฟอร์มlicense plate -> 0|1โดยเรียงตามลำดับเวลา

จากนั้นFoldList[List,{},...]สร้างรายการของส่วนเริ่มต้นทั้งหมดของรายการกฎนั้น ที่จริงแล้วมันทำให้ส่วนแรกเริ่มยุ่งเหยิง kTH เริ่มต้นส่วนปลายขึ้นเป็นรายการที่มีกฎหนึ่งที่ความลึก 2 กฎหนึ่งที่ความลึก 3, ... และหนึ่งในกฎที่ความลึกk1 ( FoldList[Append,{},...]จะให้ผลลัพธ์ที่เป็นธรรมชาติมากขึ้น) อย่างไรก็ตาม<|#|>เปลี่ยนส่วนเริ่มต้นแต่ละส่วนเหล่านี้เป็น "การเชื่อมโยง" ซึ่งมีผลที่ต้องการสองประการ: อันดับแรกจะทำให้โครงสร้างรายการแบบซ้อนที่เราเพิ่งสร้างนั้นสมบูรณ์ และประการที่สองมันบังคับให้กฎในภายหลังแทนที่กฎก่อนหน้านี้ซึ่งเป็นสิ่งที่เราต้องการที่นี่ - สำหรับรถใด ๆ ที่ออกจากที่จอดรถตอนนี้การบันทึกรายการเริ่มต้นของมันก็หายไปหมดแล้ว .

ดังนั้นทั้งหมดที่เหลือจะทำคือการCountวิธีการหลาย0s Maxที่มีอยู่ในแต่ละสมาคมเหล่านี้และใช้เวลา


1
สิ่งนี้จะทำในสิ่งที่ถูกต้องเสมอไหมหากรถยนต์มาและไปในเวลาเดียวกัน?
Christian Sievers

คำตอบของคุณอาจผิด จำนวนสูงสุดไม่จำเป็นต้องเกิดขึ้นเมื่อรถยนต์เข้ามาอีกครั้งจึงไม่ปลอดภัยที่จะลบรายการโดยใช้การเชื่อมโยง ดูรูปนี้: i.imgur.com/D5xUl3z.pngเห็นได้ชัดว่ามีรถยนต์ 3 คันที่ 16,500
Keyu Gan

@KeyuGan: ฉันไม่ได้อ้างว่าจำนวนสูงสุดเกิดขึ้นเมื่อรถเข้ามาอีกครั้ง โปรดทราบว่าวิธีการแก้ปัญหาของฉันนับจำนวนรถยนต์ในลานจอดรถ ณ เวลาที่เข้า / ออกทุกครั้งและใช้เวลาสูงสุด
Greg Martin

1
บางทีคุณอาจลองตัวอย่างที่ 2
Keyu Gan

1
ส่วนตัวผมเห็นด้วยกับคุณ :) สิ่งที่ฉันทำคือคัดลอกคำนิยามจากปัญหาดั้งเดิม ความแตกต่างที่สำคัญคือแผ่นพิมพ์ต้นฉบับนั้นต้องใช้แผ่นป้ายทะเบียนรถที่ได้รับการยอมรับจากภาพและพิมพ์เป็นผลลัพธ์สุดท้าย
Keyu Gan

5

Haskell, 76 63 61 ไบต์

2 ไบต์บันทึกโดยรูปแบบของข้อเสนอแนะของ @ nimi

f l=maximum$scanl1(+)[(-1)^c|i<-[0..8^6],(_,b,c)<-l,i==2*b+c]

คาดว่าข้อโต้แย้งเป็นรายการของอเนกประสงค์ในลำดับที่กำหนดโดยคำสั่งปัญหา

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


วางและการใช้งานimport [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b]
nimi

ฉันต้องการรถยนต์ที่เข้ามาก่อนรถขาออกดังนั้นมันจึงซับซ้อนกว่านี้เล็กน้อย แต่ฉันยังสามารถบันทึก 2 ไบต์กับความคิดของคุณ ขอบคุณ!
Christian Sievers

2

PHP 7.1, 126 117 ไบต์

for(;$s=file(i)[++$i];)$d[+substr($s,6)][$s[-2]]++;ksort($d);foreach($d as$a){$r=max($r,$n+=$a[0]);$n-=$a[1];}echo$r;

รับอินพุตจากไฟล์iละเว้นบรรทัดแรก -rทำงานด้วย
ต้องขึ้นบรรทัดใหม่ในอินพุต แทนที่-2ด้วย-3สำหรับ Windows

ชำรุด

# generate 2-dim array; first index=time, second index=0/1 (in/out);
# values=number of cars arriving/leaging; ignore plate number
for(;$s=file(i)[++$i];) # read file line by line (includes trailing newline)
    $d[+substr($s,6)][$s[-2]]++;    # substring to int=>time, last but one character=>1/0
ksort($d);                      # sort array by 1st index (time)
foreach($d as$a)    # loop through array; ignore time
{
    $r=max($r,                      # 2. update maximum count
        $n+=$a[0]                   # 1. add arriving cars to `$n` (current no. of cars)
    );
    $n-=$a[1];                      # 3. remove leaving cars from `$n`
}
echo$r;                         # print result

ขออภัยคุณสามารถใช้อาเรย์ของอเนกประสงค์เป็นอินพุตถ้าคุณกำลังเขียนฟังก์ชั่น เพื่อนของฉันและฉันเชื่อว่ามันเป็นวิธีที่ดีในการทำให้ภาษาที่ไม่ใช่กอล์ฟแข่งขันได้มากขึ้นหากเรากำลังพูดถึงปัญหาที่ไม่มีการป้อนข้อมูลที่ซับซ้อน
Keyu Gan

@KeyuGan: ขอบคุณสำหรับคำใบ้; แต่ด้วยอาร์เรย์เป็นอินพุตฉันต้องการฟังก์ชันและนั่นจะมีค่าใช้จ่ายสองไบต์ทั้งสองมีอาร์เรย์ของ triplets และ triplet ของอาร์เรย์ ฟังก์ชั่นการทำแผนที่อาเรย์และการเรียงลำดับที่กำหนดเองมีขนาดใหญ่ใน PHP วิธีเดียวที่ฉันสามารถบันทึกสิ่งใดก็ตามที่ฉันเตรียมไว้$dเป็นอินพุตหรือเรียงลำดับ (ตามเวลาและเข้า / ออก) และสิ่งที่ท้าทายก็คือการท้าทายมากเกินไป อินพุตที่ถูกจัดตำแหน่งttttt i plateจะประหยัดได้ 17 ไบต์และอีก 19 ตัวที่มีการนับสอดคล้องกับหมายเลขเพลต
ติตัส

2

C, 147 ไบต์

stdinโปรแกรมที่สมบูรณ์อ่านข้อมูลจาก

int r[86402]={},u,i,n,t;g(s,o){for(;s<86401;n<r[s]?n=r[s]:0,++s)r[s+o]+=o?-1:1;}main(){for(n=0;scanf("%d%d%d",&u,&t,&i)==3;g(t,i));printf("%d",n);}

ลองบน ideone


ฉันเชื่อว่ามันปลอดภัยที่จะลบช่องว่างระหว่าง%d
Keyu Gan

โอ๊ะขอบคุณ ฉันใช้ไม่scanfพอฉันเดา
owacoder

cinฉันรัก LOL
Keyu Gan


2

อ็อกเทฟ, 50 , 64 38 ไบต์

@(A)-min(cumsum(sortrows(A)(:,2)*2-1))

เหมือนกับคำตอบ Mathematicaของ @Greg Martin

ฟังก์ชันรับอาร์เรย์ที่มี 3 คอลัมน์ [time, i/o,plateN]

คำตอบก่อนหน้า:

@(A){[t,O]=A{:};max(cumsum(sparse({++t(!O),t}{2},1,!O*2-1)))}{2}

ฟังก์ชั่นรับเพียงสองอินพุตt: เวลาและO: I / O จากสององค์ประกอบแรกของอาร์เรย์เซลล์Aที่มีอินพุตสามตัว!

เมทริกซ์กระจัดกระจายสร้างขึ้นเพื่อนับสำหรับแต่ละจำนวนเวลาที่บันทึกไว้ของรถยนต์ที่มีอยู่ สำหรับเวลาที่ออก + 1 จะถือว่าเป็นการออกจากรถยนต์และการเปลี่ยน 1 สอดคล้องกับ -1 และ 0 เปลี่ยนเป็น 1 การ
ใช้เบาบางนี่เป็นสิ่งสำคัญมากเนื่องจากรถยนต์หลายคันอาจเดินทางมาถึงหรือออกในเวลาเดียวกัน
จากนั้นจะคำนวณยอดรวมสะสมที่แทนจำนวนรถยนต์ปัจจุบันในล็อตและสูงสุดของมันที่พบ


ฉันจำได้ว่าอาร์เรย์ของเซลล์รองรับ Octave รองรับซึ่งหมายความว่าคุณสามารถใช้อาร์เรย์อเนกประสงค์สามอันเป็นอินพุตได้ ข้อ จำกัด นี้เป็นไปตามรุ่นก่อนหน้าของ M5 และระบุว่า 'อาร์เรย์ของอเนกประสงค์' ฉันได้อธิบายไว้ใน M5
Keyu Gan

@KeyuGan ฉันคิดว่าข้อ จำกัด การประดิษฐ์ใหม่ของคุณนั้นไม่จำเป็นเพิ่มขึ้น 14 ไบต์ของรหัสของฉัน ดังนั้นคุณยังใหม่ต่อไซต์นี้จะดีกว่าถ้ามีคำถามที่มีข้อ จำกัด น้อยที่สุดเพื่อดึงดูดผู้มีส่วนร่วมมากขึ้น
rahnema1

2

JavaScript (ES6), 63 73 71 ไบต์

d=>Math.max(...d.sort((a,[b,c])=>a[s=0]-b||a[1]-c).map(e=>s+=1-e[1]*2))

[time, inout, plate]นี้ยอมรับการป้อนข้อมูลเป็นอาร์เรย์ของรายการที่สั่ง โชคไม่ดีที่ความจริงที่ว่าเวลาขาเข้าที่เหมือนกันหมายความว่ารถทั้งสองคันได้รับการพิจารณาในล็อตเดียวในขณะนี้ขั้นตอนวิธีการเรียงลำดับจะต้องสั่งซื้อ0ก่อน1ซึ่งมีราคา 11 ไบต์

เครดิต

  • ฉันบันทึก 1 ไบต์ด้วยการย้ายกะและการคูณภายในฟังก์ชันแผนที่อย่างสมบูรณ์ (ขอบคุณนีล)
  • ฉันบันทึกอีกสองไบต์โดยใช้อาร์กิวเมนต์ destructured ในฟังก์ชัน sort (ขอบคุณ edc65)

การสาธิต

// test the two examples
console.log([[[36000,1],[16500,1],[16,0],[3300,0],[6500,1],[32800,0],[16400,0],[16501,1],[16500,0],[8800,1],[3300,0]],[[16400,0],[16500,1],[16500,0],[16600,1]]].map(
// answer submission
d=>Math.max(...d.sort((a,[b,c])=>a[s=0]-b||a[1]-c).map(e=>s+=1-e[1]*2))
));


ดูเหมือนว่ารหัสของคุณใช้งานไม่ได้ดีd=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];ฉันควรพิมพ์ 2 หรือไม่
Keyu Gan

ในกรณีทดสอบ 4 รายการมีเพียง 2 คันเท่านั้น ฉันได้จัดรูปแบบแล้วเพื่อให้ตรงกับคำสั่งซื้อของคุณ
Keyu Gan

@KeyuGan ขออภัยในความเข้าใจผิดฉันไม่ทราบว่าคุณกำลังอ้างถึงตัวอย่างที่สอง ตอนนี้ได้รับการแก้ไขแล้ว
Patrick Roberts

ฉันรู้ว่าอัลกอริทึมของคุณไม่ได้ขึ้นอยู่กับจำนวนแผ่น อย่างไรก็ตามฉันแนะนำว่าควรรวมอยู่ในคำจำกัดความของคำสั่งอินพุตเพียงแค่ปล่อยให้เป็นลำดับสุดท้าย)
Keyu Gan

1
@ edc65 จริง ๆ แล้วมีเพียง 2 bytes ไม่ใช่ 4 นี่ก็เป็น 71 bytes:d=>Math.max(...d.sort(([a,b],[c,d])=>a-b||c-d).map(e=>s+=1-e[1]*2,s=0))
Patrick Roberts

2

JavaScript (ES6), 8368 70 ไบต์

แก้ไข: แก้ไขเพื่อสนับสนุนตัวอย่างที่ 2

รับอินพุตเป็นอาร์เรย์ของ[in_out, time, plate]อาร์เรย์ แต่plateคอลัมน์จะถูกละเว้นจริง

a=>a.sort(([a,b],[c,d])=>b-d||a-c).map(v=>a=(n+=1-v[0]*2)<a?a:n,n=0)|a

ทดสอบ


อ่านin_outคอลัมน์แทนของคอลัมน์ควรจะช่วยให้คุณประหยัดหกไบต์:plate v=>n+=1-v[2]*2
Neil

สิ่งนี้ไม่ถูกต้องสำหรับตัวอย่างที่สองดังนั้นหากคุณแก้ไขอีกครั้งคุณจะต้องคำนึงถึงสิ่งนั้นด้วย (เนื่องจากการแก้ไขครั้งล่าสุดนี้เป็นก่อนที่จะเพิ่มตัวอย่างที่สองมันได้รับการยกเว้นทางเทคนิคจากการปฏิบัติตามและฉันไม่อิจฉาเลย!)
Patrick Roberts

@PatrickRoberts จะพยายามแก้ไขเมื่อฉันกลับหน้าคอมพิวเตอร์ ^^
Arnauld

@ นีลจับดี! ฉันต้องเขียนใหม่เพื่อรองรับตัวอย่างที่ 2 แต่ฉันก็ทำตามคำแนะนำของคุณ
Arnauld
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.