Vấn đề đầy đủ


36

Một thách thức với các quy tắc đơn giản nhưng thuật toán không tầm thường. :-)

Bài tập

Lấy đầu vào ở dạng số nguyên được phân tách bằng dấu cách:

N A B S

Trong đó N là độ dài cạnh của ma trận vuông 2D chứa đầy các số duy nhất (số nguyên) nằm giữa A và B. Đối với mỗi hàng và cột trong ma trận này, tổng luôn luôn giống nhau: S. (Nói cách khác, ma trận là một hình vuông bán ma thuật).

Chú thích:

Tất cả các số đều dương. Ngoại lệ là A, có thể là 0.

Ví dụ

Dành cho

3 1 10000 2015

một giải pháp hợp lệ sẽ là

nhập mô tả hình ảnh ở đây

Dành cho

8 1 300 500

một giải pháp hợp lệ sẽ là

nhập mô tả hình ảnh ở đây

Đầu ra

Đầu ra của bạn phải là một bảng ASCII. Ví dụ cho ví dụ đầu tiên ở trên:

 384  159 1472
1174  499  342
 457 1357  201

Số nguyên liên kết phải được đệm bởi khoảng trắng. Chiều rộng của mỗi cột là chiều rộng của số nguyên lớn nhất trong cột đó.

Chấm điểm

Đây là , vì vậy mã ngắn nhất tính bằng byte thắng. Các lỗ hổng tiêu chuẩn được áp dụng (đặc biệt là về tích hợp sẵn để giải quyết vấn đề này). Bạn không cần phải quan tâm đến đầu vào sai hoặc không thể (bao gồm cả số âm). Vui lòng cung cấp một đầu ra mẫu trong câu trả lời của bạn (bắt buộc) cho ví dụ thứ hai ở trên.


1
Chúng ta có được phép tạo các số ngẫu nhiên giữa A và B cho đến khi chúng tổng hợp chính xác và là duy nhất không?
lirtosiast

Chỉ để kiểm tra, A, B, và Ncó thể được tiêu cực?
xnor

2
minxomat, tôi không nói đó là giải pháp tốt nhất tôi có thể nghĩ ra, tôi đang nói nó có thể là ngắn nhất có thể.
lirtosiast

3
@LuisMendo Bạn phải tạo một đầu ra mẫu theo nhiệm vụ. Nếu bạn có thể quản lý điều này trong suốt cuộc đời mình bằng cách tiếp cận vũ phu, tôi sẽ rất ấn tượng. :-). Tôi có thể loại trừ nó, nhưng nó sẽ quá mờ nhạt, vì giải pháp phổ biến nhất (đó là GA) vẫn liên quan đến tính ngẫu nhiên. Ngoài ra tôi không muốn thay đổi các quy tắc khi ai đó có thể làm việc trên một giải pháp.
mınxomaτ

1
@minxomat Tất cả ba đối số của bạn đều là những điểm rất tốt :-)
Luis Mendo

Câu trả lời:


19

CJam, 119 91 byte

q~:M;),>:R;(:L{{R{ML)d/-Y#)mr}$L/L<2{{M1$:+-+}%z}*:U:+__O|=R*-}gU{:s_:,:e>f{Se[}}%zSf*N*}M?

Đây là một cách tiếp cận có thể chứng minh chính xác, không xác định.

Trên máy tính để bàn của tôi, trường hợp thử nghiệm thứ hai thường kết thúc sau chưa đầy 10 phút.

Trường hợp đầu tiên kết thúc ngay lập tức. Hãy thử trực tuyến trong trình thông dịch CJam .

Chạy mẫu

$ cjam grid.cjam <<< '8 1 300 500'
77  66  37 47  56  46 86  85
63 102  70 72  49  54 81   9
62  69  58 57  71  17 48 118
64  65  67 87  53  44 80  40
73  60  55 89  51  76 84  12
68  59  28 78  74  38 50 105
61  75  52 43 125  83 42  19
32   4 133 27  21 142 29 112

Ý kiến

Không có giới hạn thời gian, chúng ta chỉ có thể tạo ngẫu nhiên các hình vuông cho đến khi tìm thấy một hình vuông hợp lệ. Cách tiếp cận này dựa trên ý tưởng đó, thêm hai tối ưu hóa:

  • Thay vì giả ngẫu nhiên tạo ra hình vuông có độ dài cạnh N , chúng tôi tạo ra các hình vuông có độ dài cạnh N-1 , thêm một cột để tạo thành hình chữ nhật N × (N-1) có các hàng có tổng S , sau đó một hàng để tạo thành một hình vuông bên chiều dài N có các cột có tổng S .

    Kể từ khi tổng các yếu tố của tất cả các cột sẽ NS và tổng các yếu tố của người đầu tiên N-1 dòng là (N-1) S , hàng cuối cùng cũng sẽ có tổng S .

    Tuy nhiên, quá trình này có thể tạo ra một ma trận không hợp lệ, vì không có gì đảm bảo rằng tất cả các yếu tố của hàng và cột cuối cùng sẽ là duy nhất hoặc nằm trong phạm vi [A ... B] .

  • Chọn một hình vuông các số nguyên duy nhất trong [A ... B] và độ dài cạnh N-1 đồng nhất ngẫu nhiên sẽ mất quá nhiều thời gian. Chúng tôi bằng cách nào đó phải ưu tiên các hình vuông có cơ hội cao hơn dẫn đến một hình vuông có độ dài cạnh N hợp lệ sau khi áp dụng quy trình chi tiết trong điểm đạn trước đó.

    Cho rằng mỗi hàng và cột phải có một khoản S , các yếu tố của nó có trung bình S / N . Do đó, chọn nhiều yếu tố gần với mức trung bình đó sẽ tăng cơ hội của chúng tôi.

    Đối với mỗi I trong [A ... B] , chúng tôi giả ngẫu nhiên chọn một số float giữa 0(I - S / N) 2 + 1 và sắp xếp các phần tử của [A ... B] theo các số float được chọn. Chúng tôi giữ các số N 2 đầu tiên và đặt chúng theo thứ tự đọc trong một hình vuông.

    Giả sử phân phối đồng đều hoàn toàn tất cả các số thực từ 0 đến (I - S / N) 2 + 1 trong mỗi bước, tất cả các ô vuông đều có xác suất được chọn bằng không, nghĩa là quá trình sẽ kết thúc.

q~          e# Read all input from STDIN and evaluate it.
:M;         e# Save "S" in M and discard it from the stack.
),>:R;      e# Transform "A B" into [A ... B], save in R and discard.
(:L         e# Save "N - 1" in L and keep it on the stack.
{           e# If L is non-zero:
  {         e#   Do:
    R{      e#     For each I in R:
      ML)d/ e#       Compute M/Double(L+1).
      -Y#   e#       Subtract the result from I and square the difference.
      )mr   e#       Add 1 and pick a non-negative Double below the result.
    }$      e#     Sort the values of I according to the picks.
    L/      e#     Split the shuffled R into chunks of length L.
    L<      e#     Keep only the first L chunks.
    2{      e#     Do twice:
      {     e#       For each row of the  L x L array.
        M1$ e#       Push M and a copy of the row.
        :+- e#       Add the integers of the row and subtract their sum from M.
        +   e#       Append the difference to the row.
      }%    e#
      z     e#       Transpose rows and columns.
    }*      e#
    :U:+    e#     Save the result in U and concatenate its rows.
    __O|    e#     Push two copies. Deduplicate the second copy.
    =R*     e#     Push R if all elements are unique, an empty array otherwise.
    -       e#     Remove the result's elements from U's elements.
  }g        e#   If the resulting array is non-empty, repeat the loop.
  U{        e#   For each row in U:
    :s      e#     Convert its integers into strings.
    _:,     e#     Copy and replace each string with its length.
    :e>     e#     Compute the maximum length.
    f{      e#     For each integer, push the maximum length; then
      Se[   e#       Left-pad the integer with spaces to that length.
    }       e#
  }%        e#
  z         e#   Transpose rows with columns.
  Sf*N*     e#   Join columns by spaces, rows by linefeeds.
}M?         e# Else, push M.
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.