Mảng Sandwich


8

(Chuyển thể từ Bài toán C của vòng loại đầu tiên của Cuộc thi lập trình ACM 2012/2013 )

Bạn có một số mảng, được đặt tên là A 1 , A 2 , ..., A n , mỗi mảng được sắp xếp theo thứ tự tăng dần. Mỗi mục trong mảng sẽ là số nguyên 32 bit.

Một bánh sandwich là một tập hợp các chỉ số j 1 , j 2 , ..., j n sao cho A 1 [j 1 ] A 2 [j 2 ] ≤ .... A n [j n ].
A i [0] là phần tử đầu tiên của A i .

Đưa ra một số mảng, xuất ra mọi bánh sandwich có thể có mà bạn có thể có từ các mảng đó, được phân tách bằng một dòng mới.

Nếu có một chức năng tích hợp nào đó thực hiện điều này trong ngôn ngữ của bạn, đừng sử dụng nó.

Đầu vào có thể được đưa ra theo bất kỳ cách nào, đầu ra phải được phân tách bằng khoảng trắng, nhưng có thể được cung cấp theo bất kỳ thứ tự nào.

Trường hợp thử nghiệm:
[[1, 5, 7, 10], [2, 6, 6, 8, 12], [4, 5, 9]]

Đầu ra:

0 0 0
0 0 1
0 0 2
0 1 2
0 2 2
0 3 2
1 1 2
1 2 2
1 3 2
2 3 2

Trường hợp thử nghiệm:
[[10, 20, 30], [1, 2, 3]]

Đầu ra:

Mã ngắn nhất sẽ thắng.


1
Những giá trị nào các mảng có thể chứa? Chỉ có số nguyên dương?
Ilmari Karonen

@IlmariKaronen: Chúng cũng sẽ chứa các số nguyên âm.
beary605

@PeterTaylor: Để đơn giản, chúng sẽ là các số nguyên 32 bit.
beary605

@DavidCarraher: Đây là trường hợp thử nghiệm tiếp theo. Tôi nên làm cho nó rõ ràng hơn.
beary605

Cảm ơn. Bây giờ tôi thấy rằng giải pháp hiện tại của tôi chỉ hoạt động cho các mảng gồm 3 phần tử. Tôi sẽ phải làm việc nhiều hơn một chút để khái quát nó.
DavidC

Câu trả lời:


2

APL (33)

↑1-⍨B/⍨{(⍳⍴A)∘≡⍋⍵⌷¨A}¨B←,⍳⊃∘⍴¨A←⎕

Đầu vào được đọc từ keyboad, nhưng nó phải được đưa ra dưới dạng danh sách APL, tức là

(1 5 7 10) (2 6 6 8 12) (4 5 9)

Giải trình:

  • B←,⍳⊃∘⍴¨A←⎕: A được đánh giá đầu vào, B là tất cả các bộ chỉ số có thể có trong danh sách được cho trong A.
  • {(⍳⍴A)∘≡⍋⍵⌷¨A}¨B: cho mỗi bộ chỉ mục, lấy các giá trị từ danh sách ( ⍵⌷¨A) và xem chúng có được sắp xếp ( (⍳⍴A)∘=⍋) không
  • B/⍨: chọn từ B tất cả các bộ chỉ mục trong đó biểu thức trước là đúng (nghĩa là tất cả các bánh sandwich)
  • 1-⍨: trừ một từ tất cả các chỉ số, bởi vì câu hỏi này giả định các mảng dựa trên 0 và mảng APL được dựa trên 1 theo mặc định.
  • : sắp xếp danh sách các bộ chỉ mục dưới dạng ma trận (vì vậy mỗi bộ nằm trên một dòng riêng)

3

Toán học 120 130

Biên tập

Phiên bản này hoạt động với các mảng có kích cỡ khác nhau.


l = List;
g = Grid@Cases[Outer[l, Sequence @@ MapIndexed[l, #, {2}], 1]~Flatten~(Length[#] - 1), 
x_ /; LessEqual @@ x[[All, 1]] == True :> x[[All, 2, 2]] - 1] &

Sử dụng

g@{{10, 20, 30}, {1, 22, 3}}
g@{{1, 5, 7, 10}, {2, 6, 6, 8, 12}, {4, 5, 9}}
g@{{10, 20, 30}, {1, 2, 3}}
g@{{1, -2, 3}, {-12, -7, 8, 9, 6}, {3, 99, 9}, {100, 10, -23}, {90, 10}}

các kết quả


Giải trình

Sử dụng ví dụ đầu tiên ở trên,

a = {{10, 20, 30}, {1, 22, 3}}

MapIndexedthiết lập các chỉ số cho tất cả các yếu tố. Lưu ý: Mathicala bắt đầu đếm bằng 1. (Sau này chúng ta sẽ tính đến điều đó.)

MapIndexed[l, a, {2}]

{{{10, {1, 1}}, {20, {1, 2}}, {30, {1, 3}}}, {{1, {2, 1}}, {22, {2, 2}}, {3, {2, 3}}}}}


Outertạo ra tất cả các danh sách, mỗi ứng cử viên như một mảng bánh sandwich và các chỉ số của các yếu tố của chúng; %chứa kết quả từ đầu ra trước. Các con số, 1022tôi đã nhấn mạnh sau khi chúng là đầu ra, đề cập đến một mảng bánh sandwich {10,22}vẫn chưa được xác định như vậy.

Outer[l, Sequence @@ %, 1]~Flatten~(Length[a] - 1)

{{{10, {1, 1}}, {1, {2, 1}}}, {{ 10 , {1, 1}}, { 22 , {2, 2}}}, {{10, { 1, 1}}, {3, {2, 3}}}, {{20, {1, 2}}, {1, {2, 1}}}, {{20, {1, 2}}, {22, {2, 2}}}, {{20, {1, 2}}, {3, {2, 3}}}, {{30, {1, 3}}, {1, {2, 1}}}, {{30, {1, 3}}, {22, {2, 2}}}, {{30, {1, 3}}, {3, {2, 3}}}}


Caseskiểm tra từng yếu tố ở trên để xác định xem LessEqualmối quan hệ (nhỏ hơn hoặc bằng) có được giữ hay không. Các kết quả hiển thị dưới đây là những trường hợp trong đó các mảng sandwich được phát hiện. Một lần nữa, tôi nhấn mạnh {10,22}trong đầu ra.

Cases[%, x_ /; LessEqual @@ x[[All, 1]] == True]

{{{ 10 , {1, 1}}, { 22 , {2, 2}}}, {{20, {1, 2}}, {22, {2, 2}}}}


%%đề cập đến kết quả áp chót. :>, [RuleDelayed] trả về các phần của các trường hợp quan tâm, cụ thể là các chỉ số của các mảng sandwich.  -1sửa lỗi cho thực tế là Mathicala bắt đầu mảng bằng 1 thay vì 0. 

Cases[%%, 

x_ /; LessEqual @@ x [[Tất cả, 1]] == Đúng:> x [[Tất cả, 2, 2]] - 1]

{{0, 1}, {1, 1}}


Gridhiển thị kết quả trong một lưới. Hàng đầu tiên 0 1có nghĩa là phần tử 0 từ danh sách con đầu tiên (tức là 10 ) và phần tử 1 từ danh sách phụ thứ hai (tức là 22 ) tạo thành mảng sandwich đầu tiên được tìm thấy.

Grid@%

0 1

1 1


Tôi không thích câu trả lời này vì bạn đơn giản hóa câu trả lời của mình bằng cách sửa các mảng số.
FUZxxl

Nếu bạn có nghĩa là nó chỉ hoạt động cho mảng 3 "hàng", tôi chia sẻ sự không thích của bạn. Vấn đề phải làm với việc cho phép LessEquallàm việc với các mảng có kích thước không xác định. Có thể có những trường hợp khác mà giả định tương tự cản trở tính tổng quát. Khi tôi có cơ hội, tôi sẽ khái quát cách tiếp cận.
DavidC

@FUZxxl Tôi đã có thể khái quát hóa cách tiếp cận. Hãy xem.
DavidC

3

GolfScript, 51 ký tự

~:A{,}%{*}*,{A{,.@.@/\@%}%\;}%{:k,,{.A=\k==}%.$=},`

Ví dụ đầu vào (trên stdin):

[[1 5 7 10] [2 6 6 8 12] [4 5 9]]

Ví dụ đầu ra (tới thiết bị xuất chuẩn):

[[0 0 0] [0 0 1] [0 0 2] [0 1 2] [1 1 2] [0 2 2] [1 2 2] [0 3 2] [1 3 2] [2 3 2]]

(Lưu ý rằng đầu vào phải được cung cấp mà không có dấu phẩy, nếu không chương trình rất có thể sẽ bị sập.)


Tôi đoán tôi nên thêm một số giải thích về cách mã này hoạt động:

  • ~:Achỉ đánh giá đầu vào dưới dạng mã GolfScript và gán kết quả (một mảng các mảng) cho A. Nó cũng để lại một bản sao Atrên ngăn xếp cho bước tiếp theo.

  • {,}%thay thế từng mảng con bằng độ dài của nó và {*}*nhân các độ dài đó lại với nhau, đưa ra tổng số ứng cử viên sandwich có thể. Số này sau đó được chuyển đổi ,thành một mảng gồm nhiều số nguyên liên tiếp bắt đầu từ 0.

  • {A{,.@.@/\@%}%\;}%chuyển đổi mỗi số thành một ứng cử viên sandwich tương ứng (nghĩa là một mảng các chỉ số hợp lệ thành từng mảng con trong A). Ví dụ, với đầu vào ở trên, 0sẽ lập bản đồ đến [0 0 0], 1để [1 0 0], 2đến [2 0 0], 3để [3 0 0], 4đến [0 1 0]và vân vân. (Tìm hiểu chính xác làm thế nào mã hoàn thành phần còn lại như một bài tập cho người đọc quan tâm.)

  • {:k,,{.A=\k==}%.$=},lọc các ứng cử viên sandwich bằng cách ánh xạ từng phần tử vào các phần tử tương ứng của các mảng con của A(vì vậy, ví dụ như [0 0 0]sẽ mang lại [1 2 4], [1 0 0]sẽ mang lại [5 2 4], v.v., cho đầu vào ở trên), sắp xếp mảng kết quả và so sánh nó với một bản sao chưa được sắp xếp . Nếu chúng bằng nhau, mảng đã được sắp xếp, và do đó ứng cử viên thực sự là một bánh sandwich.

  • Cuối cùng, `chỉ cần biến mảng bánh sandwich được lọc thành một chuỗi cho đầu ra.


Chúng phải được ngăn cách bởi khoảng trắng, vì vậy khoảng trắng hoặc tab cũng hoạt động.
beary605

OK, tôi đã thay đổi định dạng đầu ra.
Ilmari Karonen

1

R - 89 ký tự

i=do.call(expand.grid,lapply(x,seq_along))
i[apply(diff(t(mapply(`[`,x,i)))>=0,2,all),]-1

Ở đâu

x = list(c(1, 5, 7, 10), c(2, 6, 6, 8, 12), c(4, 5, 9))

hoặc là

x = list(c(10, 20, 30), c(1, 2, 3))

1

Con trăn 149 141 140

import itertools as I;x=input();r=range;print[p for p in I.product(*map(r,map(len,x)))if all(x[i][p[i]]<=x[i+1][p[i+1]]for i in r(len(x)-1))]

Python có một thư viện itertools hữu ích có thể tạo ra hoán vị. Điều này chỉ lặp đi lặp lại trên tất cả các hoán vị có thể có của các chỉ số hợp lệ và kiểm tra xem chúng có thỏa mãn các tiêu chí hay không.

Tôi nghĩ rằng tôi có thể làm điều này ngắn hơn, vẫn làm việc trên nó.

Chỉnh sửa: Bây giờ tất cả một dòng để bạn đọc (trong) thuận tiện!


r=rangesẽ lưu một ký tự.
beary605

Cảm ơn vì tiền hỗ trợ. Nó chưa bao giờ xảy ra với tôi rằng tôi có thể bí danh các chức năng thư viện.
scleaver

1

Con trăn 120

f=lambda p,k=0:['%i '%j+m for j,v in enumerate(p[0])if v>=k for m in f(p[1:],v)]if p else['']
print'\n'.join(f(input()))

... vẫn nghĩ, "liệt kê" là một từ rất dài.


1

GolfScript (44 ký tự)

~{.,,]zip}%{{`{+}+1$\/}%\;}*{2%.$=},{(;2%}%`

Định dạng đầu vào và đầu ra giống như mục nhập của Ilmari.

Bản giới thiệu

Sự cố thô sơ:

Ánh xạ mỗi hàng đầu vào thành một mảng các cặp [value index]

{.,,]zip}%

Gấp một sản phẩm của Cartesian qua các hàng

{{`{+}+1$\/}%\;}*

Lọc cho những người có mục 0, 2, 4, v.v. không giảm.

{2%.$=},

Ánh xạ từng cái xuống các mục 1, 3, 5, v.v.

{(;2%}%

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.