|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
接上一期的python小练习
有了之前的那些函数以后,主程序就相对好写了。
不断交替进行横行和纵行的运算,剔除不可行的候选排列,最终剩下的就是答案。
完整程序:
- # -*- coding: utf-8 -*-
- """
- Created on Tue May 9 20:57:18 2017
- @author: XuJ06
- """
- def getdata(file):
- f = open(file)
- flag = -1
- size = []
- hor = []
- ver = []
- temp = [size,hor,ver]
- for i in f.readlines():
- if i[0]=='#':
- flag+=1
- elif i[0]=='\n':
- pass
- else:
- temp[flag].append([int(e) for e in i.split()])
- return (size[0][0],size[0][1],hor,ver)
- def candidate(num,maxlen):
- '''''针对给出的排列方式,递归获得所有的备选排列 点亮为# '''
- candi = []
- for i in range(maxlen+2-sum(num)-len(num)):
- cans = '_'*i + '@'*num[0]
- if len(num)==1:
- tail = '_'*(maxlen-len(cans))
- candi.append(cans+tail)
- else:
- tail = ['_'+j for j in candidate(num[1:], maxlen-len(cans)-1)]
- candi.extend([cans + j for j in tail])
- return candi
- def findinit(x,y,hnum,vnum):
- '''''找出每一行和每一列的备选排列'''
- candidateH = []
- candidateV = []
- for i in range(y):
- candidateH.append(candidate(hnum[i],x))
- for i in range(x):
- candidateV.append(candidate(vnum[i],y))
- return candidateH, candidateV
- def check(candi,pos,flag):
- '''''对某一行(列)在给定位置和给定状态选择不冲突的备选方案'''
- newcandi = []
- for i in candi:
- if i[pos]== flag:
- newcandi.append(i)
- return newcandi
- def solver(file):
- xsize,ysize,hnum,vnum = getdata(file)
- candiH, candiV = findinit(xsize,ysize,hnum,vnum)
- result = []
- for i in range(xsize):
- result.append([' ' for j in range(ysize)])
- count = 0
- target = xsize*ysize
- while count < target:
- for index in range(xsize):#先针对每一行
- i = candiH[index]
- if i == 'done':
- continue
- elif len(i) == 1:
- for j in range(ysize):
- if result[index][j] == ' ':
- count+=1
- result[index][j] = i[0][j]
- candiV[j] = check(candiV[j],index,i[0][j])
- i = 'done'
- else:
- for j in range(ysize):
- if result[index][j] != ' ':
- continue
- for k in i[1::]:
- if k[j]!=i[0][j]:
- break
- else:
- result[index][j] = i[0][j]
- count+=1
- candiV[j] = check(candiV[j],index,i[0][j])
- for index in range(ysize):#再针对每一列,除个别变量外,代码相同
- i = candiV[index]
- if i == 'done':
- continue
- elif len(i) == 1:
- for j in range(xsize):
- if result[j][index] == ' ':
- count+=1
- result[j][index] = i[0][j]
- candiH[j] = check(candiH[j],index,i[0][j])
- i = 'done'
- else:
- for j in range(xsize):
- if result[j][index] != ' ':
- continue
- for k in i[1::]:
- if k[j]!=i[0][j]:
- break
- else:
- result[j][index] = i[0][j]
- count+=1
- candiH[j] = check(candiH[j],index,i[0][j])
- for line in result:
- print(''.join(line))
- print(solver('up.txt'))
复制代码
输出:
- ___________________@@@_@@_______
- __________________@@@@@@@@______
- _________________@@@@@@@@@@_____
- _________________@@@___@__@_____
- _________________@@@@@_@@_@_____
- _________________@@@@@_@@_@_____
- ________________@@@@___@__@_____
- _____________@@@@@@@@@@@@@@@____
- ___________@@@@@@@@@@@@@@@@@@@__
- __________@@@@@@_@@@@@@@@@@@@@@_
- _________@@@@@@___@_@@@@@@@@@@@@
- _________@@@@@@_____@_@@@@@@@@@@
- ________@@@@@@@___@@__@_@@@@@@@@
- ________@@@@@@_@_@_@@___@_@_@__@
- ________@@@@@___@__@@@@________@
- ________@@@@@_@@@@_@_@@@@_@_@_@_
- ________@@@@@___@_@___@@@@@@@@__
- _________@@@@@_@@__@___@@@@@@@@_
- _________@@@@@@__@__@@___@_@@@__
- __________@@@@@@_@@@__@@_____@__
- ___________@@@@@@___@___@@@@@___
- @___________@@@@@@__@@@_________
- @@___________@@@@@@@___@@_______
- @@@__@@@___@@@@@@@@@@_@@@@______
- @@@@@@@@@_@@@@@@@@@@@@____@_____
- @@@@@@@@@@@@@@@@@@@@@@____@_____
- _@@@@@@@@@@@@@@@@@@@@@_@@@@_____
- __@__@@@@@@@@@@@@@@@@@____@_____
- ___@@__@@@@@@@@_@@@@@_____@_____
- ________@@_____@@_____@@@@______
- __________@@@@@__@@_@___@_______
- ___________________@@@@@________
复制代码 |
|