关注
 消消乐问题:    用一个感染函数,一个标志矩阵(初始值为1),把与初始点相同且连成一片的位置,对应在标志矩阵的位置改为0,然后与初始矩阵进行对应位置相乘的操作,则初始矩阵被消除的位置变为0,其他位置数字保持不变,然后执行下沉操作,对下沉完成的矩阵继续执行开始的消除操作    开始写的版本是贪心的,就是每次消除最大数量的点,但后来感觉不合适,不是最优解。后来改成每次从上到下,从左到右顺序‘感染’,只要凑够三个就删除        从上到下,从左到右顺序消除:   import numpy as np
class returndata():#每个点给上一个点返回的信息(与本点相邻且相同的点有多少个?)
    subnum = 0
    def __init__(self,subnum):
        self.subnum = subnum
#感染函数(给定flaglist矩阵,把能连城一片的点的位置,对应在flaglist中表为0)
def infect(i, j, number, checkerboard, flagList):
    if i<0 or i >= len(checkerboard) or j<0 or j>= len(checkerboard[0]) or checkerboard[i][j] != number or \
    flagList[i][j]==0 or number == 0:
        return returndata(0)
    flagList[i][j] = 0
    sumsubnum = returndata(1)
    #从上下左右四个方向继续“感染”
    a = infect(i + 1, j, checkerboard[i][j], checkerboard, flagList)
    b = infect(i - 1, j, number, checkerboard, flagList)
    c = infect(i, j + 1, checkerboard[i][j], checkerboard, flagList)
    d = infect(i, j - 1, number, checkerboard, flagList)
    sumsubnum.subnum += a.subnum+b.subnum+c.subnum+d.subnum
    return sumsubnum#返回值为 从此点出发,最多能删除的点的个数
#下沉函数,把不是0的数都下沉下去
def down(matrix):
    for i in range(len(matrix)-1,0,-1):
        for j in range(len(matrix[0])):
            if matrix[i][j]==0:
                for h in range(i-1,-1,-1):
                    if matrix[h][j]!=0:
                        matrix[i][j] = matrix[h][j]
                        matrix[h][j] = 0
    return matrix
checkerboard = np.array([[3, 1, 2, 1, 1, ], \
                         [1, 1, 1, 1, 3], \
                         [1, 1, 1, 1, 1], \
                         [1, 1, 1, 1, 1], \
                         [3, 1, 2, 2, 2]])
row = checkerboard.shape[0]  # 获取行数
col = checkerboard.shape[1]  # 获取列数
flagList = [[1] * col for i in range(row)]  # 创建标志矩阵,初始值为1,能删除的位置变为0
flagList = np.array(flagList)
#print(checkerboard)
for i in range(row):
    for j in range(col):
        flagList = [[1] * col for k in range(row)]#消除矩阵
        flagList = np.array(flagList)
        result = infect(i, j, checkerboard[i][j], checkerboard, flagList)
        if result.subnum>=3:#如果相同点连通个数大于等于3,则进行消除操作
            checkerboard = checkerboard*flagList
            checkerboard = down(checkerboard)
            print(checkerboard)
count = 0#最后剩下的不能删除的点的个数
for lst in checkerboard:
    for x in lst:
        if x!=0:
            count+=1
print(count)     贪心版本:   import numpy as np
class returndata():#返回的信息(与本点相邻的点有多少个?)
    subnum = 0
    def __init__(self,subnum):
        self.subnum = subnum
def infect(i, j, number, checkerboard, flagList):#感染函数
    if i<0 or i >= len(checkerboard) or j<0 or j>= len(checkerboard[0]) or checkerboard[i][j] != number or \
    flagList[i][j]==0 or number == 0:
        return returndata(0)
    flagList[i][j] = 0
    sumsubnum = returndata(1)
    a = infect(i + 1, j, checkerboard[i][j], checkerboard, flagList)
    b = infect(i - 1, j, number, checkerboard, flagList)
    c = infect(i, j + 1, checkerboard[i][j], checkerboard, flagList)
    d = infect(i, j - 1, number, checkerboard, flagList)
    sumsubnum.subnum += a.subnum+b.subnum+c.subnum+d.subnum
    return sumsubnum
def down(matrix):#把不是0的都沉下去
    for i in range(len(matrix)-1,0,-1):
        for j in range(len(matrix[0])):
            if matrix[i][j]==0:
                for h in range(i-1,-1,-1):
                    if matrix[h][j]!=0:
                        matrix[i][j] = matrix[h][j]
                        matrix[h][j] = 0
    return matrix
checkerboard = np.array([[3, 1, 2, 1, 1, ], \
                         [1, 1, 1, 1, 3], \
                         [1, 1, 1, 1, 1], \
                         [1, 1, 1, 1, 1], \
                         [3, 1, 2, 2, 2]])
row = checkerboard.shape[0]  # 获取行数
col = checkerboard.shape[1]  # 获取列数
flagList = [[1] * col for i in range(row)]
flagList = np.array(flagList)
print(checkerboard)
dic = {}#key:可删除点的个数 value:对应个数的标志矩阵(0 1矩阵)
while True:
    dic.clear()
    for i in range(row):
        for j in range(col):
            flagList = [[1] * col for k in range(row)]#消除矩阵
            flagList = np.array(flagList)
            result = infect(i, j, checkerboard[i][j], checkerboard, flagList)
            if result.subnum>=3:
                dic[result.subnum] = flagList
    if dic=={}:#结束条件(不能再消除的时候结束)
        break
    #if max(dic.keys())<3:
    #    break
    maxdeletematrix = dic.get(max(dic.keys()))
    checkerboard = checkerboard*maxdeletematrix
    checkerboard = down(checkerboard)
    print(checkerboard)
count = 0#最后剩下的不能删除的点的个数
for lst in checkerboard:
    for x in lst:
        if x!=0:
            count+=1
print(count)
  查看原帖
  点赞  3
相关推荐
09-04 22:37
  电子科技大学 算法工程师   点赞 评论 收藏   
分享
 09-04 20:20
  门头沟学院 运营   点赞 评论 收藏   
分享
 牛客热帖
更多 
 正在热议
 更多 
 # 校招生月薪1W算什么水平 #
 22322次浏览 148人参与
# 硬件人的简历怎么写 #
 310948次浏览 3055人参与
# “vivo”个offer #
 34684次浏览 270人参与
# 我是面试官,请用一句话让我破防 #
 19991次浏览 112人参与
# 中美关税战对我们有哪些影响 #
 39992次浏览 342人参与
# i人适合做什么工作 #
 8937次浏览 84人参与
# 快手技术岗信息交流阵地 #
 16322次浏览 82人参与
# 华为保温 #
 104007次浏览 397人参与
# 如果秋招能重来,我会____ #
 31939次浏览 266人参与
# 哪些行业值得去? #
 3548次浏览 43人参与
# 机械人,签完三方你在忙什么? #
 64880次浏览 243人参与
# 牛友们,签完三方你在忙什么? #
 118987次浏览 957人参与
# 苦尽甘来时,再讲来时路 #
 28205次浏览 405人参与
# 华为池子有多大 #
 108464次浏览 750人参与
# 读研or工作,哪个性价比更高? #
 76020次浏览 766人参与
# 如果上班像打游戏,你最想解锁什么技能 #
 6313次浏览 64人参与
# 美团开奖 #
 195430次浏览 1043人参与
# 为了实习逃课值吗? #
 25054次浏览 228人参与
# 大家实习每天都在干啥 #
 97623次浏览 536人参与
# 秋招许愿,本周能____ #
 24958次浏览 212人参与
# 秋招什么时候开投比较合适? #
 110252次浏览 807人参与
# 小厂实习有必要去吗 #
 70422次浏览 346人参与
 投递携程等公司10个岗位
投递携程等公司10个岗位