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]