나는이 도전이 1 년이 넘었 음을 알고 있지만, "답이없는"에서 이것을 발견하고 나에게 흥미로워 보였다.
"루트"셀의 숫자가 각 지역에서 유일하게 중요한 숫자라고 가정하면 (예제에서 제외 가능) 다음은 역 추적 솔루션입니다.
파이썬 (3) , 355 (351) 349 바이트
from itertools import*
def f(a):
D=len(a[0])+1;S={D*r+c for r in range(len(a))for c in range(D-1)if a[r][c]};s=[{x,*t}for x in S for t in combinations({x-D,x-1,x+1,x+D}&S,a[x//D][x%D]-1)]
def B(s,S,d=1):
if{0}>S:return a
if[]==s:return 0
h,*t=s
if h<=S:
for x in h:a[x//D][x%D]=d
return h<=S and B(t,S-h,d+1)or B(t,S,d)
return B(s,S)
온라인으로 사용해보십시오!
입력 형식은 2D 정수 목록이고 공백은 0이며 출력 형식은 숫자 당 하나의 영역을 나타내는 2D 정수 목록입니다. 지역 번호는 하나에서 시작합니다. 빈 셀에 대해서는 0이 예약되어 있습니다 (입력에서와 같이). 주어진 입력을 해결할 수없는 경우, 함수는 단일 제로 (거짓 값)를 반환합니다.
예를 들어, 테스트 케이스 5는 다음과 같이 입력됩니다.
[[2,3,2],
[3,4,3],
[0,4,0],
[3,3,3],
[2,3,2],
[0,3,0]]
출력은
[[1,1,1],
[2,2,2],
[0,2,0],
[3,4,5],
[3,4,5],
[0,4,0]]
코멘트가없는 언 골프 드 :
from itertools import*
def f(a):
# Rows, cols, fake-cols to prevent neighbors wrap around
R,C=len(a),len(a[0]);D=C+1
# All valid cells represented as integers
S={D*r+c for r in range(R) for c in range(C) if a[r][c]}
# All valid regions rooted at each cell
s=[{x,*t} for x in S for t in combinations({x-D,x-1,x+1,x+D}&S,a[x//D][x%D]-1)]
# Start backtracking
return backtrack(a,s,S,D)
# a: array to fill in the region numbers
# s: current candidates of regions
# S: current remaining cells to cover
# D: constant from f
# d: recursion depth == group number in the result
def backtrack(a,s,S,D,d=1):
# Empty S: the board is correctly covered, return the result
if not S:return a
# Empty s: no more candidate regions to use, return false
if not s:return 0
h,*t=s
# h is not a subset of S: h is not a valid cover, try with the rest using same depth
if not h<=S:return backtrack(a,t,S,D,d)
# h is a valid cover, write d to the cells in h
for x in h:a[x//D][x%D]=d
return backtrack(a,t,S-h,D,d+1)or backtrack(a,t,S,D,d)
온라인으로 사용해보십시오!
참고 : 이것은 NP- 완전으로 잘 알려진 특수 세트 포장의 경우입니다 . 이 특정 문제는 세트 크기가 제한적이며 (최대 4 개) 다항식 시간에 "좋은"세트 패킹을 찾기위한 근사 알고리즘이 있지만 가능한 최대 세트 패킹을 보장하지는 않습니다 (이 문제에서 엄격하게 요구됨).
4
유효한 입력 인 경우 테스트 케이스도 다루어야 합니다.