python写算法题:leetcode: 37. Sudoku Solver

115 篇文章 0 订阅
import math
class Solution(object):
    def mask(self, box, i, j):
        v=(1<<9)-1 
        for i0 in xrange((i/3)*3, (i/3)*3+3):
            for j0 in xrange((j/3)*3, (j/3)*3+3):
                v&=~box[(i0,j0)]
        for i0 in xrange(0, 9):
            v&=~box[(i0,j)]
            v&=~box[(i,i0)]
        return v

    def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        box={}
        box2={}
        assume=[]
        for i,line in enumerate(board):
            for j,c in enumerate(line):
                box[(i,j)]=0
                if c!='.':
                    box[(i,j)]=(1<<(int(c)-1))
                else:
                    box2[(i,j)]=(1<<9)-1  
        
        self.dump("init:", box)
        while True:
            renew = True
            while renew:
                resolved=1
                for i in xrange(0,9):
                    for j in xrange(0,9):
                        if box[(i,j)]!=0: 
                            continue
                        resolved=0
                        box2[(i,j)]=self.mask(box, i, j)
                renew=False
                for i in xrange(0,9):
                    if resolved==2: break
                    for j in xrange(0,9):
                        if box[(i,j)]!=0:
                            continue
                        if box2[(i,j)] == 0:
                            resolved=2
                            break
                        if (~box2[(i,j)]+1)&box2[(i,j)] == box2[(i,j)]:
                            box[(i,j)]=box2[(i,j)] 
                            renew=True
                            break
            if resolved==1:
                break
            self.dump("step:%d,%d"%( resolved, len(assume)), box)
            if resolved==2:
                while len(assume)>0:
                    i,j,lastv,box = assume[-1]
                    box2[(i,j)]=self.mask(box, i, j)
                    remain=(box2[(i,j)]/lastv-1)*lastv
                    newv=(~(remain)+1)&remain
                    if newv>0:
                        assume[-1]=(i,j,newv,box.copy())
                        box[(i,j)]=newv
                        break
                    del assume[-1]
                    
            if resolved==0:
                for i in xrange(0,9):
                    for j in xrange(0,9):
                        if box[(i,j)]==0:
                            break
                    if box[(i,j)]==0: 
                        break
                self.dump("before assume:", box)
                loop=True
                dumpbox=box.copy()
                box[(i,j)]=(~box2[(i,j)]+1)&box2[(i,j)]
                assume.append((i,j,box[(i,j)], dumpbox))
                self.dump("after  assume:", box)
                
        self.dump("final:", box)
        
        for i in xrange(0,9):
            for j in xrange(0,9):
                if box[(i,j)]>0: 
                    board[i][j]=str(int(math.log(box[(i,j)],2))+1)
        return True
                
    def dump(self, info, box):
        return
        print info
        for i in xrange(9):
            for j in xrange(9):
                if box[(i,j)] == 0:
                    print '.',
                else: print int(math.log(box[(i,j)], 2)+1),
            print

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值