최소 비용 블록 대각선


10

주 대각선에 1의 정사각형 블록이 있고 다른 곳에서는 0 인 이진 블록 대각 행렬 을 고려하십시오 . 이러한 행렬을 "유효한"행렬이라고하겠습니다.

예를 들어, 다음은 유효한 4x4 행렬입니다.

1 0 0 0     1 1 0 0     1 0 0 0     1 0 0 0     1 1 0 0    1 1 1 1
0 1 0 0     1 1 0 0     0 1 1 0     0 1 1 1     1 1 0 0    1 1 1 1
0 0 1 0     0 0 1 0     0 1 1 0     0 1 1 1     0 0 1 1    1 1 1 1
0 0 0 1     0 0 0 1     0 0 0 1     0 1 1 1     0 0 1 1    1 1 1 1

이러한 행렬을 설명하는 다른 방법은 왼쪽 상단에서 오른쪽 하단까지 정사각형 1 블록 체인이 있으며 모서리마다 닿아 있고 그 밖의 모든 곳은 0입니다.

대조적으로, 여기에 잘못된 4x4 행렬이 있습니다 :

1 0 1 0     1 0 1 0     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 1 1 1     0 1 0 1     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
1 0 0 1     1 0 1 0     0 0 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 0 1 0     0 1 0 1     0 0 0 1     1 0 0 0     0 0 1 1    0 0 0 0

당신이 주어집니다 n에 의해 n입력으로 진 매트릭스 - 최소 번호 것입니다 0당신이 설정해야 비트 1유효한 매트릭스를 얻기 위하여는?

전처리되지 않는 한, 0과 1 의 nby n행렬을 나타내는 편리한 문자열, 목록 또는 행렬 형식을 취하는 함수 나 프로그램을 작성할 수 있습니다 . 행은 어떤 방식으로도 명확하게 분리되어야하므로 1D 비트 배열과 같은 형식은 허용되지 않습니다.

이것은 이므로 목표는 프로그램의 바이트 수를 최소화하는 것입니다.

예를 들어 입력이

0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 1

그런 다음 5 0비트를 설정 1하여 얻을 수 있기 때문에 대답은 5입니다 .

1 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 1 0
0 0 0 0 1

그리고 이것은 필요한 최소 수입니다. 그러나 입력이

0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

오른쪽 상단 1이 모든 1의 행렬 이므로 유일하게 유효한 5x5 행렬이므로 답은 24 입니다.

테스트 사례

여기서 테스트는 2D 정수 배열로 표시됩니다.

[[0]] -> 1
[[1]] -> 0
[[0,1],[0,0]] -> 3
[[1,0],[0,0]] -> 1
[[0,0,0],[0,1,0],[0,0,0]] -> 2
[[0,1,0],[0,0,0],[0,1,0]] -> 7
[[0,1,0],[1,0,0],[0,0,1]] -> 2
[[1,1,1],[1,1,1],[1,1,1]] -> 0
[[0,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,0]] -> 4
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -> 8
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,1,0]] -> 14
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,1,0,0]] -> 14
[[0,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 7
[[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 11
[[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,1]] -> 5
[[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 24
[[0,0,0,1,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 23
[[0,1,0,0,0],[1,0,0,0,0],[0,0,1,0,0],[0,0,0,0,1],[0,0,0,1,0]] -> 4
[[0,1,1,1,0],[0,1,1,0,1],[0,1,1,1,0],[0,1,0,0,1],[0,0,0,0,0]] -> 14

노트

답변:


3

MATL , 46 43 바이트

nX^tQt:qZ^!tsb=Z)"@!"@1$l]@n$YdG-Q?6MG>zvX<

입력은 행 분리 자로 세미콜론이있는 2D 배열입니다. 예를 들어, 마지막 테스트 케이스의 입력은

[0,1,1,1,0;0,1,1,0,1;0,1,1,1,0;0,1,0,0,1;0,0,0,0,0]

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 (코드는 약간 수정되어 모든 입력을 취합니다. 결과는 몇 초 후에 나타납니다)

설명

입력을 N × N 행렬로 둡니다. 코드는 먼저 적절한 행렬 크기를 생성하는 모든 ( N +1) 튜플의 블록 크기를 계산합니다. 예를 들어,에 대한 N 튜플은 (4) = 0 0 0 0 4, 0 0 0 1 3..., 4 0 0 0 0. 각 튜플마다 해당 블록 크기로 블록 대각선 행렬을 만듭니다. 그런 다음 행렬 1이 입력의 모든 항목을 포함하는지 확인 하고 입력 1에없는 항목 수를 기록합니다. 최종 결과는 얻은 모든 숫자의 최소값입니다.

nX^      % Implicit input  an N×N matrix. Get N
t        % Duplicate N
Qt:q     % Vector [0 1 ... N]
Z^       % Cartesian power. Gives 2D array
!ts      % Transpose, duplicate, sum of each column
b=       % Logical vector that equals true if the sum is N
Z)       % Filter columns according to that. Only keep columns that sum to N. Each 
         % column is the size of one block
"        % For each column
  @      %   Push that column
  "      %   For each entry of that column
    @    %     Push that entry
    1$l  %     Square matrix with that size, filled with 1
  ]      %   End
  @n     %   Column size. This is the number of blocks in the block-diagonal matrix
  $Yd    %   Build block-diagonal matrix from those blocks
  G-Q    %   Subtract input matrix element-wise, and add 1
  ?      %   If all entries are nonzero (this means each that entry that is 1 in the
         %   block-diagonal matrix is also 1 in the input matrix)
    6M   %   Push block-diagonal matrix again
    G>   %   For each entry, gives 1 if it exceeds the corresponding entry of the
         %   input, that is, if the block-diagonal matrix is 1 and the input is 0
    z    %   Number of 1 entries
    v    %   Concatenate vertically with previous values
    X<   %   Take minimum so far
         %   Implicit end
         % Implicit end
         % Implicit display

3

numpy가있는 Python, 102

from numpy import*
lambda M:sum(diff([k for k in range(len(M)+1)if(M|M.T)[:k,k:].any()-1])**2)-M.sum()

효율적인 알고리즘. 대각선에서 블록을 분리 할 수있는 "목 지점"을 찾습니다. 위와 오른쪽뿐만 아니라 아래와 왼쪽 모두 0입니다. 최소 블록은 목 지점 사이의 블록입니다.

??000
??000
00???
00???
00???

블록의 길이는 연속 목 지점 간의 차이이므로 이들의 제곱 합의 총 면적입니다. 원래 행렬의 합을 빼면 0에서 1까지 필요한 플립 수가 제공됩니다.


2

Pyth, 45 바이트

-hSlMf@I.DRlQx1sQTms.b^+LsYN2d+0._ds.pM./lQss

어려운 작업이므로 꽤 길다.

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

s.pM./lQ의 모든 정수 파티션을 계산합니다 len(matrix). ms.b^+LsYN2d+0._d좌표 쌍으로 변환합니다. 예를 들어 파티션 [1, 2, 2]의는 5변환에를 가져옵니다 [[0,0], [1,1], [1,2], [2,1], [2,2], [3,3], [3,4], [4,3], [4,4].

f@I.DRlQx1sQT그런 다음 행렬을 완전히 겹치는 파티션을 필터링합니다 (매트릭스 .DRlQx1sQ에서 활성 셀의 모든 좌표 쌍을 계산).

-hSlM...ss 남아있는 각 파티션의 셀 수를 세고 가장 적은 셀이있는 셀을 선택하고 이미 활성화 된 셀을 뺍니다.


0

Matricks , 180 바이트 (비경쟁)

Matricks는 2 개의 데이터 유형 (float 및 matricies)만으로 매트릭스 문제 (예 : 이와 같은)를 처리하기 위해 최근에 만든 새로운 esolang입니다. 아직 완전히 기능하지는 않았지만 여전히 많은 누락 된 작업이 있습니다 (이 과제를 위해 일부 기능을 추가해야했습니다). 어쨌든, 여기 코드가 있습니다 :

il=1:j3;:bdx;;;s1::L;j1;;
b{q:1;mgr:c;|gc:r;|(r=c)|(gr-1:c;|gr:c+1;)&(rec)|(gr+1:c;|gr:c-1;)&(cer):l:L;};z:(l-1)/2;B1;s1::g1:;-1;ig1:;=0:j2;:j1;;
s1::d{q:1;};;kg1:;-g:;;
kg:;*-1+1;

설명

첫 번째 부분 il=1:j3;:...;은 배열의 크기가 1인지 확인합니다. 배열 인 경우 kg:;*-1+1;간단한 0 <-> 1함수 인 마지막 줄로 이동 합니다.

그렇지 않으면 나머지 코드로 계속 진행됩니다. bdx;;;0,0을 현재 합계로 설정하고 s1::L;j1;아래 행에 셀에 카운터를 만듭니다.

다음 줄은 조금 더 복잡합니다. 행렬의 크기 인 n시간 을 실행하는 루프입니다 n. 세 번째 테스트 사례를 예로 사용하겠습니다. 두 번째 줄에 처음 도착하면 행렬은 다음과 같습니다.

1 0 1
2 0 0

먼저, 우리는 행렬 이해에 들어갑니다 {q:1;m...;}. 이렇게하면 대각선이 만들어지고 채워야하는 0을 정리하기 위해 최선을 다합니다.이 모든 것은 간단한 부울 연산자를 사용하여 수행됩니다. 그런 다음 현재 행렬 앞에 추가하여 다음을 제공합니다.

    V--data we want to keep
1 1 1 0 1 <-|
1 1 2 0 0 <-- old matrix

그런 다음을 사용하여 이전 행렬을 잘라 내고을 사용 z:(l-1)/2;하여 전체 행렬을 왼쪽으로 회전합니다 B1;. 그러면 다음 반복을 위해 준비된 행렬이 제공됩니다.

1 1 1
2 1 1

마지막으로 카운터를 줄이고 확인한 다음 계속합니다 ig1:;=0:j2;:j1;;

루프가 끊어지면 새 합계를 찾아 카운터의 이전 지점을로 설정합니다 s1::d{q:1;};;. 마지막으로, 우리는 차이를 취하고 return kg1:;-g:;;합니다. k현재 배열을 값으로 설정하고 인쇄는 암시 적입니다.

...

보시다시피 Matricks 는 매우 장황하고 골프 언어가 아닙니다. 그러나 나는 그것을 과시하고 싶었다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.