题目:
这道题说实话一开始没怎么看懂(过于菜鸡),然后发现就是一个类似于一个简单版的数独题目,目前也没接触什么很厉害的算法,所以就瞎jb做了一下。
个人思路:
1)先把input的一些东西搞成列表,就不用在函数里面每次传参了。
2)然后就先根据N 画个n*n 的二维数组 元素可以先设成0。
3)然后根据题目给的一些限制条件,比如说如果有个点的clue为1 说明只能看到最高的一栋楼 那么就设那个点为N;如果有个点的clue为N 那么正好是顺序排的 就一行填好。
4)然后剩余的空 我用dfs 一个个的试着填好了 只要确保行列没有重复
5)然后最后在输出的前面检查一下是否符合全部的clues就可以了
1.这是初始化一些input (过于粗糙可以忽略
在这里插入代码片
def initialize():
global rowTop,rowBottom,columnLeft,columnRight
line = input().split(',')
rowTop = line[0]
rowBottom = line[-1]
line.remove(rowBottom)
line.remove(rowTop)
rowTop = list(rowTop.split().pop(1))
rowBottom = list(rowBottom.lstrip(' '))
columnLeft = []
columnRight = []
for j in line:
columnLeft.append(j[1])
columnRight.append(j[2])
N = len(rowTop)
return N
2.初始化一个这个图
x = [[0 for i in range(N)]for j in range(N)] # initialize the board
3.然后下面函数对应思路三,把几个limit填好
def detech1(N): # Find the clues with value of 1
for i in range(N):
if rowTop[i] == '1':
x[0][i] = N
for i in range(N):
if rowBottom[i] == '1':
x[N-1][i] = N
for i in range(N):
if columnLeft[i] == '1':
x[i][0] = N
for i in range(N):
if columnRight[i] == '1':
x[i][N-1] = N
return
def detechN(N): # Find the clues with value of N
for i in range(N):
if rowTop[i] == str(N):
for j in range(N):
x[j][i] = j+1
for i in range(N):
if rowBottom[i] == str(N):
for j in range(N):
x[N-1-j][i] = j+1
for i in range(N):
if columnLeft[i] == str(N):
for j in range(N):
x[i][j] = j+1
for i in range(N):
if columnRight[i] == str(N):
for j in range(N):
x[i][N-1-j] = j+1
return
4.然后这里就是确认一下有没有重复出现的数字(1-N)
def is_valid(r,c,fill): # check if there is no repetition but not with clues
for i in range(N):
if x[r][i] == fill:
return False
if x[i][c] == fill:
return False
5.下面几个函数作用就是分上下左右的去检查clues对不对
def checkWithClues_ColumnL(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N):
if x[j][i] > temp:
counter += 1
temp = x[j][i]
if counter != int(rowTop[i]):
flag = False
break
return flag
def checkWithClues_RowU(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N):
if x[i][j] > temp:
counter += 1
temp = x[i][j]
if counter != int(columnLeft[i]):
flag = False
break
return flag
def checkWithClues_RowD(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N-1,-1,-1):
if x[i][j] > temp:
counter += 1
temp = x[i][j]
if counter != int(columnRight[i]):
flag = False
break
return flag
def checkWithClues_ColumnR(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N-1,-1,-1):
if x[j][i] > temp:
counter += 1
temp = x[j][i]
if counter != int(rowBottom[i]):
flag = False
break
return flag
下面就是搞了我这个菜鸡很久的dfs(终于好像会了
差不多就是前面几个if 控制着换行 和 往下移动。 套的基本的搜索框架。然后差不多就结束了
def dfs(N,i,j): #i代表行,j代表列
if i == N: #当全部填完没有重复后,开始检查是不是和clues也正确
if checkWithClues_ColumnL(N) and checkWithClues_RowU(N) and checkWithClues_RowD(N) and checkWithClues_ColumnR(N) == True:
print(x)
return
if j == N:#换行
dfs(N,i+1,0)
return
if x[i][j] != 0:#走到下一格
dfs(N,i,j+1)
return
for fill in range(1,N+1):
if is_valid(i,j,fill) == False:
continue
x[i][j] = fill
dfs(N,i,j+1)
x[i][j] = 0
完整代码(没有循环5次去求全部解 ,甚至没有格式化输出,做出来答案对了就打游戏 继续学习去了
# AcslSkyscraper
def initialize():
global rowTop,rowBottom,columnLeft,columnRight
line = input().split(',')
rowTop = line[0]
rowBottom = line[-1]
line.remove(rowBottom)
line.remove(rowTop)
rowTop = list(rowTop.split().pop(1))
rowBottom = list(rowBottom.lstrip(' '))
columnLeft = []
columnRight = []
for j in line:
columnLeft.append(j[1])
columnRight.append(j[2])
N = len(rowTop)
return N
def detech1(N): # Find the clues with value of 1
for i in range(N):
if rowTop[i] == '1':
x[0][i] = N
for i in range(N):
if rowBottom[i] == '1':
x[N-1][i] = N
for i in range(N):
if columnLeft[i] == '1':
x[i][0] = N
for i in range(N):
if columnRight[i] == '1':
x[i][N-1] = N
return
def detechN(N): # Find the clues with value of N
for i in range(N):
if rowTop[i] == str(N):
for j in range(N):
x[j][i] = j+1
for i in range(N):
if rowBottom[i] == str(N):
for j in range(N):
x[N-1-j][i] = j+1
for i in range(N):
if columnLeft[i] == str(N):
for j in range(N):
x[i][j] = j+1
for i in range(N):
if columnRight[i] == str(N):
for j in range(N):
x[i][N-1-j] = j+1
return
def is_valid(r,c,fill): # check if there is no repetition but not with clues
for i in range(N):
if x[r][i] == fill:
return False
if x[i][c] == fill:
return False
def checkWithClues_ColumnL(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N):
if x[j][i] > temp:
counter += 1
temp = x[j][i]
if counter != int(rowTop[i]):
flag = False
break
return flag
def checkWithClues_RowU(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N):
if x[i][j] > temp:
counter += 1
temp = x[i][j]
if counter != int(columnLeft[i]):
flag = False
break
return flag
def checkWithClues_RowD(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N-1,-1,-1):
if x[i][j] > temp:
counter += 1
temp = x[i][j]
if counter != int(columnRight[i]):
flag = False
break
return flag
def checkWithClues_ColumnR(N):
flag = True
for i in range(N):
counter = 0
temp = -1
for j in range(N-1,-1,-1):
if x[j][i] > temp:
counter += 1
temp = x[j][i]
if counter != int(rowBottom[i]):
flag = False
break
return flag
def dfs(N,i,j): #i代表行,j代表列
if i == N: #当全部填完没有重复后,开始检查是不是和clues也正确
if checkWithClues_ColumnL(N) and checkWithClues_RowU(N) and checkWithClues_RowD(N) and checkWithClues_ColumnR(N) == True:
print(x)
return
if j == N:#换行
dfs(N,i+1,0)
return
if x[i][j] != 0:#走到下一格
dfs(N,i,j+1)
return
for fill in range(1,N+1):
if is_valid(i,j,fill) == False:
continue
x[i][j] = fill
dfs(N,i,j+1)
x[i][j] = 0
N = initialize()
x = [[0 for i in range(N)]for j in range(N)] # initialize the board
detech1(N)
detechN(N)
dfs(N,0,0)
(就想把我做的这些竞赛题归归类,然后几年后来看看我有多菜