emmmm..依然牛客网上的题,难度标识才一颗星,但是感觉自己看代码看了好久才理解实现的过程。
题目描述:如下图,有10*10个不同颜色的方块,每个方块可能是红、绿、蓝、黄、紫5种颜色之一。当点击其中某一个方块时,如果它有相邻的同颜色方块,则将所有与此方块连续同颜色相邻的方块消除;剩下的方块中,如果下方有空位则向下移动,如果左侧整列都为空位则向左移动。
输入
输入数据有多组,每组占一行,包括一个或多个正整数,取值范围为1~100。每个数代表一次点击,数值为点击的方块编号。
以下是各色方块以及方块位置地图的初始值:
RED = 0, GREEN = 1, BLUE = 2, YELLOW = 3, PURPLE = 4;
mp = [
[0, 0, 2, 2, 1, 3, 2, 3, 0, 4],
[1, 1, 1, 2, 0, 4, 0, 3, 3, 2],
[2, 0, 0, 3, 3, 4, 2, 1, 1, 2],
[3, 0, 2, 3, 2, 0, 4, 1, 1, 0],
[3, 0, 2, 2, 4, 1, 4, 0, 3, 2],
[4, 3, 0, 0, 3, 0, 4, 3, 0, 0],
[3, 3, 1, 4, 1, 0, 2, 3, 2, 1],
[0, 3, 2, 2, 3, 1, 4, 0, 2, 1],
[1, 1, 3, 3, 0, 0, 4, 2, 2, 1],
[4, 2, 0, 0, 4, 3, 2, 0, 0, 1]
]
输出
对于每个测试实例,要求输出连续各次点击全部完成之后,红、绿、蓝、黄、紫色方块的数量;每个测试实例的输出占一行。
eg:
INPUT
6
OUTPUT
26 18 22 21 13
具体代码及详解如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Name: demo26.py
# Author: zhuzhuzhu time:2018/5/17
# Connect: [email protected]
# Desc:方块消除游戏(py2)
import Queue
import copy
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
mp = [
[0, 0, 2, 2, 1, 3, 2, 3, 0, 4],
[1, 1, 1, 2, 0, 4, 0, 3, 3, 2],
[2, 0, 0, 3, 3, 4, 2, 1, 1, 2],
[3, 0, 2, 3, 2, 0, 4, 1, 1, 0],
[3, 0, 2, 2, 4, 1, 4, 0, 3, 2],
[4, 3, 0, 0, 3, 0, 4, 3, 0, 0],
[3, 3, 1, 4, 1, 0, 2, 3, 2, 1],
[0, 3, 2, 2, 3, 1, 4, 0, 2, 1],
[1, 1, 3, 3, 0, 0, 4, 2, 2, 1],
[4, 2, 0, 0, 4, 3, 2, 0, 0, 1]
]
# bfs搜索同色
def bfs(beg):
global mp, dx, dy
# 队列长度无限长
q = Queue.Queue(maxsize=0)
# 点击位置的x,y 坐标
x = beg / 10
y = (beg - 1) % 10
block_color = mp[x][y]
if block_color == -1:
return False
"""
申请获得互斥锁,获得后,如果队列未满,则向队列中添加数据,并通知notify其它阻塞的某个线程,
释放互斥锁。由于队列无限长,这一步其实就是在添加数据。
"""
q.put((x, y))
cnt = 0
# qsize判断队列长度,不为空则循环
while q.qsize():
# get从队列中获取任务,并且从队列中移除此任务。
x, y = q.get()
# 点击位置(x, y)的周围元素
for i in range(4):
s = dx[i] + x
t = dy[i] + y
# 维度不正确或者与点击位置不同色,则结束本次循环,进入下次循环
if s < 0 or s > 9 or t < 0 or t > 9 or mp[s][t] != block_color:
continue
cnt += 1
# 若同色,则将这个位置初始化为-1,被标记为-1的数就相当于被消除了
mp[s][t] = -1
# 将(s, t)加入队列
q.put((s, t))
# 经过同色消去的处理,点击元素的位置必然发生了变化,若无变化,只能说明出错啦
if cnt == 1:
mp[beg/10][(beg - 1) % 10] = block_color
return False
return True
# 紧凑map
def merge_map():
# 初始化一个10行10列且每个元素均为-1的矩阵
tmp_mp = [[-1 for i in range(10)] for j in range(10)]
global mp
for i in range(10):
cnt = 0
for j in range(10):
# 这样可以判断有多少个同色
if mp[i][j] == -1:
cnt += 1
if cnt != 10:
for j in range(10):
tmp_mp[i][j] = mp[i][j]
mp = copy.deepcopy(tmp_mp)
# print tmp_mp
# 统计最终数量
def calc_block_num():
red = 0
green = 0
blue = 0
yellow = 0
purple = 0
# 统计红绿蓝黄紫各有多少个
for i in range(10):
for j in range(10):
if mp[i][j] == 0:
red += 1
elif mp[i][j] == 1:
green += 1
elif mp[i][j] == 2:
blue += 1
elif mp[i][j] == 3:
yellow += 1
elif mp[i][j] == 4:
purple += 1
print str(red) + ' ' + str(green) + ' ' + str(blue) + ' ' + str(yellow) + ' ' + str(purple)
actions = map(str, raw_input())
for action in actions:
if action != ' ':
if bfs(int(action)):
merge_map()
calc_block_num()
目前代码理解这块儿基本没有什么大问题(大概能说服自己),但是如果要求上手敲可能还有些费劲,所以…明天再做一遍加深记忆。