Пітон - 1669 рік
Ще досить довго, але досить швидко, щоб запустити останній приклад за секунду на моєму комп’ютері. Можливо, це можливо скоротити за рахунок швидкості, але на сьогоднішній день це майже рівнозначно коду без вогків.
Приклад виведення для останнього тестового випадку:
0 11 1 11 2 11 3 11 4 11 4 10 3 10 2 10 1 10 1 9 2 9 3 9 4 9 4 8 3 8 3 7 4 7 5 7 5 6 5 5 6 5 6 6 6 7 7 7 8 7 8 8 7 8 6 8 5 8 5 9 5 10 5 11 6 11 6 10 6 9 7 9 8 9 8 10 7 10 7 11 8 11 9 11 9 10 9 9 10 9 10 10 10 11 11 11 11 10 11 9 11 8 11 7 10 7 10 8 9 8 9 7 9 6 10 6 11 6 11 5 11 4 11 3 10 3 9 3 9 4 9 5 8 5 8 4 8 3 8 2 8 1 9 1 10 1 10 0 9 0 8 0 7 0 7 1 7 2 6 2 5 2 5 1 6 1 6 0 5 0 4 0 3 0 2 0 2 1 3 1 4 1 4 2 4 3 5 3 6 3 7 3 7 4 6 4 5 4 4 4 4 5 4 6 3 6 3 5 3 4 3 3 3 2 2 2 2 3 1 3 1 2 1 1 1 0 0 0 0 1 0 2 0 3 0 4 0 5 0 6 1 6 1 5 1 4 2 4 2 5 2 6 2 7 1 7 1 8 0 8 0 9 0 10
Код:
I=raw_input().split('\n');X=len(I[0]);Y=len(I);R=range
def S(g=0,c=0,x=0,y=0):
if y>=Y:return 0
if g==0:g=[[-1]*X for i in R(Y)];c=[[-1]*X for i in R(Y)]
o={'.':set(R(7)),'w':{1,2},'b':{3,4,5,6}}[I[y][x]].copy()
o&={0,1,3,4}if y<1 or g[y-1][x]in[0,1,5,6]else{2,5,6}
o&={0,2,4,5}if x<1 or g[y][x-1]in[0,2,3,6]else{1,3,6}
if y>Y-2:o&={0,1,5,6}
if x>X-2:o&={0,2,3,6}
if y>0 and g[y-1][x]in[2,3,4]:
if'b'==I[y][x]and g[y-1][x]!=2:return 0
if'b'==I[y-1][x]:o&={2}
elif'w'==I[y-1][x]and g[y-2][x]==2:o&={5,6}
if x>0 and g[y][x-1]in[1,4,5]:
if'b'==I[y][x]and g[y][x-1]!=1:return 0
if'b'==I[y][x-1]:o&={1}
elif'w'==I[y][x-1]and g[y][x-2]==1:o&={3,6}
h=[r[:]for r in c]
if y>0 and g[y-1][x]in[2,3,4]:
if x>0 and g[y][x-1]in[1,4,5]:
if c[y-1][x]==c[y][x-1]:
if(6 not in o)+any(any(i!=c[y-1][x]and i!=-1 for i in r)for r in c)+any(I[v][u]!='.'and(v>y)+(u>x)for v in R(y,Y)for u in R(X)):return 0
g[y][x]=6
for v in R(y,Y):
for u in R(X):
if v!=y or u>x:g[v][u]=0
for y in R(Y):
for x in R(X):
if g[y][x]>0:break
f=[];d=-1;u,v=p,q=x,y
while(u,v)!=(p,q)or-1==d:f+=[u,v];d=([0,{0,2},{1,3},{2,3},{0,3},{0,1},{1,2}][g[v][u]]-{(d+2)%4}).pop();i,j={0:(u+1,v),1:(u,v-1),2:(u-1,v),3:(u,v+1)}[d];u,v=i,j
return f
else:
for v in R(y+1):
for u in R(X):
if h[v][u]==c[y][x-1]:h[v][u]=c[y-1][x]
h[y][x]=c[y-1][x]
else:h[y][x]=c[y-1][x]
elif x>0 and g[y][x-1]in[1,4,5]:h[y][x]=c[y][x-1]
else:h[y][x]=max(max(r)for r in c)+1
for n in sorted(list(o))[::-1]:
if n==0:h[y][x]=-1
if x>X-2:i,j=0,y+1
else:i,j=x+1,y
g[y][x]=n;r=S(g,h,i,j)
if r!=0:return r
return 0
for i in S():print i,
Безголівки:
class Grid:
def __init__(self,input):
self.input = input.split('\n')
self.x = len(self.input[0])
self.y = len(self.input)
self.options = {'.':{0,1,2,3,4,5,6},'w':{1,2},'b':{3,4,5,6}}
def convert(self,grid):
directions = [None,{0,2},{1,3},{2,3},{0,3},{0,1},{1,2}]
for y in range(self.y):
for x in range(self.x):
if grid[y][x] != 0:
break
chain = []
start_pos = (x,y)
dir = -1
pos = start_pos
while dir == -1 or pos != start_pos:
chain.extend(pos)
x,y = pos
next_dir = (directions[grid[y][x]]-{(dir+2)%4}).pop()
if next_dir == 0: nx,ny = x+1,y
elif next_dir == 1: nx,ny = x,y-1
elif next_dir == 2: nx,ny = x-1,y
elif next_dir == 3: nx,ny = x,y+1
dir = next_dir
pos = (nx,ny)
return chain
def solve(self,grid=None,chain_ids=None,pos=(0,0)):
x,y = pos
if y >= self.y:
return None
if grid is None:
grid = [[-1]*self.x for i in range(self.y)]
if chain_ids is None:
chain_ids = [[-1]*self.x for i in range(self.y)]
options = self.options[self.input[y][x]].copy()
if y == 0 or grid[y-1][x] in [0,1,5,6]:
options &= {0,1,3,4}
else:
options &= {2,5,6}
if y == self.y-1:
options &= {0,1,5,6}
if x == 0 or grid[y][x-1] in [0,2,3,6]:
options &= {0,2,4,5}
else:
options &= {1,3,6}
if x == self.x-1:
options &= {0,2,3,6}
if y != 0 and grid[y-1][x] in [2,3,4]:
if self.input[y][x] == 'b' and grid[y-1][x] != 2:
return None
if self.input[y-1][x] == 'b':
options &= {2}
elif self.input[y-1][x] == 'w':
if grid[y-2][x] == 2:
options &= {5,6}
if x != 0 and grid[y][x-1] in [1,4,5]:
if self.input[y][x] == 'b' and grid[y][x-1] != 1:
return None
if self.input[y][x-1] == 'b':
options &= {1}
elif self.input[y][x-1] == 'w':
if grid[y][x-2] == 1:
options &= {3,6}
new_chain_ids = [[i for i in row] for row in chain_ids]
if y != 0 and grid[y-1][x] in [2,3,4]:
if x != 0 and grid[y][x-1] in [1,4,5]:
if chain_ids[y-1][x] == chain_ids[y][x-1]:
if 6 not in options:
return None
if any(any(i != chain_ids[y-1][x] and i != -1 for i in row) for row in chain_ids) or \
any(self.input[v][u] != '.' and (v!=y or u>x) for v in range(y,self.y) for u in range(self.x)):
return None
grid[y][x] = 6
for v in range(y,self.y):
for u in range(self.x):
if v != y or u > x:
grid[v][u] = 0
return self.convert(grid)
else:
for v in range(y+1):
for u in range(self.x):
if new_chain_ids[v][u] == chain_ids[y][x-1]:
new_chain_ids[v][u] = chain_ids[y-1][x]
new_chain_ids[y][x] = chain_ids[y-1][x]
else:
new_chain_ids[y][x] = chain_ids[y-1][x]
elif x != 0 and grid[y][x-1] in [1,4,5]:
new_chain_ids[y][x] = chain_ids[y][x-1]
else:
new_chain_ids[y][x] = max(max(row) for row in chain_ids)+1
for n in sorted(list(options),key=lambda n: -n):
grid[y][x] = n
if n == 0:
new_chain_ids[y][x] = -1
if x == self.x-1:
nx,ny = 0,y+1
else:
nx,ny = x+1,y
result = self.solve(grid,new_chain_ids,(nx,ny))
if result is not None:
return result
input = """
.....w.b.w..
ww..b...b...
.w.....b....
...wbww..b.b
....b.......
w.w.........
..w......b.b
.....bb.....
.....b.....w
w.ww..b.....
...w......w.
b..w.....b..
""".strip()
def print_grid(grid):
for y,row in enumerate(grid):
s = ""
for i in row:
s += {-1:'xxx',0:' ',1:' ',2:' | ',3:' ',4:' ',5:' | ',6:' | '}[i]
s += '\n'
for x,i in enumerate(row):
s += {-1:'x%sx',0:' %s ',1:'-%s-',2:' %s ',3:'-%s ',4:' %s-',5:' %s-',6:'-%s '}[i] % input.split('\n')[y][x]
s += '\n'
for i in row:
s += {-1:'xxx',0:' ',1:' ',2:' | ',3:' | ',4:' | ',5:' ',6:' '}[i]
s += '\n'
print s
result = Grid(input).solve()
print result