Phù hợp với các yếu tố trong lĩnh vực


11

Cho một số nguyên dương dưới 1000, hiển thị tất cả các hình chữ nhật có thể có với khu vực đó.

Bài tập

Giả sử đầu vào là 20. Chúng ta có thể tạo một hình chữ nhật 20 × 1, 10 × 2 hoặc 5 × 4, vì vậy đây là đầu ra hợp lệ:

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

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

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

Lưu ý rằng mỗi hình chữ nhật có thể xuất hiện chính xác một lần.

Các hình chữ nhật có thể xuất hiện theo bất kỳ thứ tự, định hướng hoặc vị trí nào, nhưng không có hai hình chữ nhật có thể trùng nhau hoặc chạm vào, ngay cả ở các góc. Những điều sau đây cũng hợp lệ:

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

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

Chấm điểm

Vùng hộp giới hạn (BBA) của một đầu ra là diện tích của hình chữ nhật tối thiểu bao quanh tất cả các hình chữ nhật. Trong đầu ra ví dụ đầu tiên, kích thước là 20 × 9, do đó BBA là 180. Trong đầu ra ví dụ thứ hai, kích thước là 20 × 7, vì vậy BBA chỉ là 140.

Tìm BBA của đầu ra khi đầu vào là 60, 111, 230, 400 và 480 và thêm chúng vào. Nhân tổng này với kích thước mã của bạn theo byte. Kết quả là điểm số của bạn; điểm số thấp nhất chiến thắng.

Quy tắc

  • Chương trình (hoặc hàm) phải tạo đầu ra hợp lệ cho bất kỳ số nguyên dương nào dưới 1000.
  • Đầu ra phải chứa chỉ dấu hoa thị ( *), dấu cách ( ) và dòng mới.
  • Có thể có bất kỳ khoảng trống giữa các hình chữ nhật, nhưng điều này được tính vào BBA.
  • Các dòng hoặc cột hàng đầu hoặc dấu, nếu chúng chỉ có khoảng trắng, không được tính vào BBA.

Các trường hợp đặc biệt có thể được mã hóa cứng?
Sở thích của Calvin

@ Calvin'sHob sở thích Có, nhưng tôi nghi ngờ nó sẽ giúp nhiều.
Ypnypn

3
@ Calvin'sHob sở thích Giải pháp của Volkswagen.
Cấp sông St

Câu trả lời:


3

Ruby, 228 byte * 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ột số thay đổi từ mã không mã hóa. Lớn nhất là thay đổi ý nghĩa của biến mtừ chiều cao của hình chữ nhật vuông, đến chiều cao của hình chữ nhật vuông cộng n.

Một cách tầm thường, *40đã được thay đổi thành *ncó nghĩa là rất nhiều khoảng trắng không cần thiết ở bên phải cho lớn n; và -2được thay đổi thành 0có nghĩa là hình chữ nhật được vẽ trên đáy luôn bỏ lỡ hai cột đầu tiên (điều này dẫn đến việc đóng gói kém hơn cho các số có chỉ số nhân (n/2)*2)

Giải trình

Cuối cùng tôi đã tìm thấy thời gian để trở lại điều này.

Đối với một ntrường nhỏ nhất định phải có đủ không gian cho cả hình chữ nhật dài nhất 1*nvà hình chữ nhật vuông x*y. Rõ ràng là có thể đạt được bố cục tốt nhất nếu cả hai hình chữ nhật có các cạnh dài được định hướng theo cùng một hướng.

Bỏ qua yêu cầu về khoảng trắng giữa các hình chữ nhật, chúng tôi thấy rằng tổng diện tích là (n+y)*x = (n+n/x)*xhoặc n*(x+1). Dù bằng cách nào, điều này đánh giá n*x + n. Bao gồm cả khoảng trắng, chúng ta phải thêm một phần phụ xnếu chúng ta đặt các hình chữ nhật từ đầu đến cuối hoặc nnếu chúng ta đặt các hình chữ nhật cạnh nhau. Do đó, trước đây là thích hợp hơn.

Điều này đưa ra các mức dưới đây (n+y+1)*xcho khu vực trường:

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

Điều này cho thấy thuật toán sau:

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

Thực tế có thể lấy tất cả các hình chữ nhật cho các trường hợp thử nghiệm được yêu cầu trong các giới hạn dưới đã đề cập ở trên, ngoại trừ 60, cho ra đầu ra 71 * 8 = 568 sau đây. Điều này có thể được cải thiện một chút thành 60 * 9 = 540 bằng cách di chuyển hai hình chữ nhật mỏng nhất bên phải một hình vuông rồi lên, nhưng việc tiết kiệm là tối thiểu, do đó có lẽ không đáng để thêm bất kỳ mã nào.

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

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

Điều này cho tổng diện tích 21895.

Mã bị đánh cắp

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 byte

90385 * 56 = 5061560 giả sử đầu ra giống như của Martin (tôi tin là vậy.)

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

Đây là một chức năng hữu ích khác, trong một chương trình thử nghiệm hữu ích

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]

Cung cấp cho đầu ra sau đây, để tham khảo:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.