参考资料:POJ 1691 - Painting A Board | 眈眈探求
特别注意:注意本文的升序排列语句。
一 题目描述:
给定一个矩形区域,它包含多个不重叠的方块,现在要给各方块涂颜色,并且设定了各方块的目标颜色,例如A的目标颜色为蓝色,B的为红色。
着色原则:
*1 假设为C着色,那么必须保证其上方的格子A已被涂色,否则C不能被着色;也就是说,必须从低行号开始着色,而不能反向。
*2 当为A着色之后,考虑其他与A具有相同颜色的方块是否满足*1的着色条件,如果满足,则将其同时着色。例如,与A具有相同颜色的方块包括C、E、F,那么,在给A着色之后,C满足着色条件,也将被同时着色。
*3 接下来,考虑未着色的其他方格,从上到下,进行着色。
*4 要求寻找一种方案,使得涂满所有方格的次数最少。
二 解题原则:
1. 首先,要将数据转化为矩阵数据:
1.1 根据输入数据,确定矩阵的行、列尺寸
1.2 根据输入数据,确定各矩形框的信息:
label_dict[label_i] = [i,[rr_s,cc_s,rr_e,cc_e],label_c,False,[above,under]] # 矩形参数——区域标签:区域编号+区域坐标+区域颜色+是否着色标记+[上方矩形集合、下方矩形集合]
2 以左上角顶点行号为0的矩形为初始节点,进行DFS搜索
2.1 获得当前矩形的颜色
2.1.1 获得具有相同颜色的矩形区域列表,并按左上角顶点行号从小到大排序(因为着色的顺序是从上到下,对应于行号从小到大。)
2.2 对具有相同颜色的矩形进行着色
# 1. 判断其上方是否为空,或者已经全部着色:
# 1.1 是:则进行着色
3 检测尚未着色的区域,按左上角顶点行号升序排列之后,进行DFS递归处理
4 如果所有矩形均已着色完毕,则结束返回。
三 代码实现
# http://poj.org/problem?id=1691
import math
## 数据处理子程序需要确定横纵坐标的最大值
def proData(rec_Data,rec_num):
# 将数据转化为矩阵
## 首先获得矩阵的长宽信息
temp_r=[]
temp_c = []
for i in range(rec_num):
temp_r.append(rec_Data[i][2])
temp_c.append(rec_Data[i][3])
RR = max(temp_r)
CC = max(temp_c)
## 更新矩形坐标信息
new_rec_Data = []
for i in range(rec_num):
# 共5个元素:坐标1 + 坐标2 + 颜色
## 将坐标2的横纵坐标均减1,转化为矩阵坐标,便于后续索引
temp = []
for j in range(5):
if j ==2 or j ==3:
temp.append(rec_Data[i][j]-1)
else:
temp.append(rec_Data[i][j])
new_rec_Data.append(temp)
# 建立空矩阵,用于存放数据
## 建立组别数据和颜色数据
data_group = [[0]*CC for i in range(RR)]
# data_color = [[0] * CC for i in range(RR)]
lab