พอดีกับปัจจัยในสนาม


11

รับจำนวนเต็มบวกต่ำกว่า 1,000 แสดงสี่เหลี่ยมที่เป็นไปได้ทั้งหมดกับพื้นที่นั้น

งาน

สมมุติว่าอินพุทคือ 20 เราสามารถสร้างสี่เหลี่ยมผืนผ้า 20 × 1, 10 × 2 หรือ 5 × 4 ดังนั้นนี่คือผลลัพธ์ที่ถูกต้อง:

********************

**********
**********

*****
*****
*****
*****

โปรดทราบว่าแต่ละสี่เหลี่ยมที่เป็นไปได้จะปรากฏขึ้นหนึ่งครั้ง

รูปสี่เหลี่ยมผืนผ้าอาจปรากฏขึ้นในลำดับการวางแนวหรือตำแหน่งใด ๆ แต่ไม่มีรูปสี่เหลี่ยมผืนผ้าสองรูปแบบใดที่ซ้อนทับกันหรือสัมผัสแม้ที่มุม ต่อไปนี้ถูกต้อง:

********************

            ****
**********  ****
**********  ****
            ****
            ****

เกณฑ์การให้คะแนน

พื้นที่กล่องขอบเขต (BBA) ของการส่งออกเป็นพื้นที่ของสี่เหลี่ยมขั้นต่ำที่ล้อมรอบสี่เหลี่ยมทั้งหมด ในเอาต์พุตตัวอย่างแรกขนาดคือ 20 × 9 ดังนั้น BBA คือ 180 ในเอาต์พุตตัวอย่างที่สองขนาดคือ 20 × 7 ดังนั้น BBA จึงเท่ากับ 140

ค้นหา BBA ของเอาต์พุตเมื่ออินพุตคือ 60, 111, 230, 400 และ 480 และเพิ่มขึ้น คูณผลรวมนี้ด้วยขนาดของรหัสของคุณเป็นไบต์ ผลลัพธ์คือคะแนนของคุณ คะแนนต่ำสุดชนะ

กฎระเบียบ

  • โปรแกรม (หรือฟังก์ชัน) จะต้องสร้างเอาต์พุตที่ถูกต้องสำหรับจำนวนเต็มบวกใด ๆ ที่ต่ำกว่า 1,000
  • เอาต์พุตจะต้องมีเครื่องหมายดอกจัน ( *) ช่องว่าง ( ) และบรรทัดใหม่
  • อาจมีช่องว่างระหว่างสี่เหลี่ยมมุมฉาก แต่จะนับรวมเป็น BBA
  • นำหน้าหรือต่อท้ายบรรทัดหรือคอลัมน์หากมีเพียงช่องว่างอย่านับรวมใน BBA

กรณีพิเศษสามารถฮาร์ดโค้ดได้หรือไม่?
งานอดิเรกของ Calvin

@ Calvin'sHobbies ใช่ แต่ฉันสงสัยว่ามันจะช่วยได้มาก
Ypnypn

3
@ Calvin'sHobbies โซลูชันโฟล์คสวาเกน
เลเวลริเวอร์เซนต์

คำตอบ:


3

Ruby, 228 ไบต์ * 21895 = 4992060

->n{a=(0..n*2).map{$b=' '*n}
g=0
m=n*2
(n**0.5).to_i.downto(1){|i|n%i<1&&(m=[m,n+h=n/i].min
g+=h+1
g<m+2?(a[g-h-1,1]=(1..h).map{?**i+$b}):(x=(m-h..m).map{|j|r=a[j].rindex(?*);r ?r:0}.max 
(m-h+1..m).each{|j|a[j][x+2]=?**i}))}
a}

การเปลี่ยนแปลงหลายอย่างจากโค้ดที่ไม่ได้รับการดัดแปลง หนึ่งที่ใหญ่ที่สุดคือการเปลี่ยนแปลงความหมายของตัวแปรmจากความสูงของรูปสี่เหลี่ยมผืนผ้า squarest nเพื่อความสูงของรูปสี่เหลี่ยมผืนผ้าบวก

นิด, *40ได้ถูกเปลี่ยนไป*nซึ่งหมายความว่าจำนวนมากของช่องว่างที่ไม่จำเป็นที่เหมาะสมสำหรับการมีขนาดใหญ่n; และ-2เปลี่ยนเป็น0รูปสี่เหลี่ยมที่พล็อตที่ด้านล่างมักจะพลาดสองคอลัมน์แรก (ผลลัพธ์นี้ส่งผลให้การบรรจุแย่ลงสำหรับตัวเลขที่แยกตัวประกอบเฉพาะ(n/2)*2)

คำอธิบาย

ในที่สุดฉันก็พบเวลาที่จะกลับไปที่นี้

สำหรับการได้รับnข้อมูลที่เล็กที่สุดจะต้องมีพื้นที่มากพอสำหรับทั้งสี่เหลี่ยมผืนผ้ายาวที่สุดและสี่เหลี่ยม1*n squarest x*yมันควรจะเห็นได้ชัดว่ารูปแบบที่ดีที่สุดสามารถทำได้ถ้าสี่เหลี่ยมทั้งสองมีด้านยาวของพวกเขามุ่งเน้นไปในทิศทางเดียวกัน

ละเว้นความต้องการสำหรับช่องว่างระหว่างสี่เหลี่ยมเราพบว่าพื้นที่ทั้งหมดเป็นอย่างใดอย่างหนึ่งหรือ(n+y)*x = (n+n/x)*x ทั้งสองวิธีนี้ในการประเมินn*(x+1) n*x + nรวมถึงช่องว่างเราต้องรวมพิเศษxถ้าเราวางสี่เหลี่ยมจนจบหรือnถ้าเราวางสี่เหลี่ยมเรียงกัน อดีตจึงเป็นที่นิยมมากกว่า

นี่จะให้ขอบเขตล่าง(n+y+1)*xสำหรับพื้นที่ฟิลด์ต่อไปนี้:

n     area
60    71*6=426
111  149*3=447
230  254*10=2540
400  421*20=8240
480  505*20=10100

นี่เป็นการแนะนำอัลกอริทึมต่อไปนี้:

Find the value (n+y+1) which shall be the field height
Iterate from the squarest rectangle to the longest one
  While there is space in the field height, draw each rectangle, one below the other, lined up on the left border.
  When there is no more space in the field height, draw the remaining rectangles, one beside the other, along the bottom border, taking care not to overlap any of the rectangles above.
  (Expand the field rightwards in the rare cases where this is necessary.)

เป็นไปได้จริงที่จะได้รับสี่เหลี่ยมทั้งหมดสำหรับกรณีทดสอบที่ต้องการภายในขอบเขตล่างที่กล่าวถึงข้างต้นยกเว้น 60 ซึ่งให้เอาต์พุต 71 * 8 = 568 ต่อไปนี้ สามารถปรับปรุงได้เล็กน้อยเป็น 60 * 9 = 540 โดยเลื่อนสี่เหลี่ยมที่บางที่สุดทั้งสองไปทางขวาหนึ่งสี่เหลี่ยมจัตุรัสขึ้นไป แต่การบันทึกมีค่าน้อยที่สุดดังนั้นจึงอาจไม่คุ้มค่ารหัสพิเศษใด ๆ

10
12
15
20
30
60
******
******
******
******
******
******
******
******
******
******

*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
*****  *
       *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
****   *
       *
***    *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
*** ** *
    ** *
    ** *
    ** *
    ** *
    ** *
    ** *
    ** *
    ** *
    ** *
    ** *
    ** *

นี่ให้พื้นที่ทั้งหมด 21895

รหัสไม่ได้รับการตอบ

f=->n{
  a=(0..n*2).map{' '*40}                                      #Fill an array with strings of 40 spaces
  g=0                                                         #Total height of all rectangles
  m=n                                                         #Height of squarest rectangle (first guess is n) 
  (n**0.5).to_i.downto(1){|i|n%i<1&&(puts n/i                 #iterate through widths. Valid ones have n%i=0. Puts outputs heights for debugging.
    m=[m,h=n/i].min                                           #Calculate height of rectangle. On first calculation, m will be set to height of squarest rectangle.
    g+=h+1                                                    #Increment g
    g<n+m+2?                                                  #if the rectangle will fit beneath the last one, against the left margin
      (a[g-h-1,1]=(1..h).map{'*'*i+' '*40})                      #fill the region of the array with stars
    :                                                         #else  
      (x=(n+m-h..n+m).map{|j|r=a[j].rindex('* ');r ?r:-2}.max    #find the first clear column
      (n+m-h+1..n+m).each{|j|a[j][x+2]='*'*i}                    #and plot the rectangle along the bottom margin
    )
  )}
a}                                                            #return the array

puts f[gets.to_i]


1

Ruby, 56 ไบต์

90385 * 56 = 5061560 สมมติว่าเอาต์พุตเหมือนกับมาร์ติน (ฉันเชื่อว่ามันเป็น)

->n{1.upto(n){|i|i*i<=n&&n%i==0&&puts([?**(n/i)]*i,'')}}

นี่เป็นอีกฟังก์ชั่นที่มีประโยชน์ในโปรแกรมทดสอบที่มีประโยชน์

f=->n{1.upto(n){|i|i*i<=n&&n%i==0&&print(n/i,"*",i,"\n")};puts}

f[60];f[111];f[230];f[400];f[480]

ซึ่งให้ผลลัพธ์ต่อไปนี้สำหรับการอ้างอิง:

60*1
30*2
20*3
15*4
12*5
10*6

111*1
37*3

230*1
115*2
46*5
23*10

400*1
200*2
100*4
80*5
50*8
40*10
25*16
20*20

480*1
240*2
160*3
120*4
96*5
80*6
60*8
48*10
40*12
32*15
30*16
24*20
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.