原题链接:
# https://blog.csdn.net/z8110/article/details/48003467 # https://exp-blog.com/algorithm/poj/poj2362-square/
一 注意事项:
1. 当dfs递归过程涉及字典、队列时,要首先将其重新赋值给新变量:
# 传递字典
new_dict = {}
for key in dict.keys():
if key != start: #去除已访问的节点
new_dict[key] = dict[key]
# 传递列表
new_parent = []
for i in parent:
new_parent.append(i)
2. 在将数据转成矩阵,并将数据索引用其矩阵坐标表示时,将字典键值的值用[]表示,便于后续索引取值。
3. 关于dfs的递归过程,需要明确以下信息:
3.1 进行终止判断的条件是什么?
3.2 进行更新的参数是哪些?
3.3 进行循环迭代时的节点是哪些?
4. 此外,对于输入参数的处理——
4.0 对数据进行降序排列:
for i in range(n):
temp = list(map(str,input().strip().split(' ')))
data_size.append(int(temp[0]))
data.append(sorted(temp[1:],reverse=True)) # 降序排列
4.1 有时也可以加入条件判断,从而对输入数据进行预分类:
# #1 边不是整数,返回no
# #2 边小于最大值,返回no
if int(subData[0]) > int(Sum//size) or int(float(Sum/size)*size) != int(int(Sum/size)*size):
print("no")
二 代码实现:
# POJ 2362 - Square
# https://blog.csdn.net/z8110/article/details/48003467
# https://exp-blog.com/algorithm/poj/poj2362-square/
# DFS:只要找到一种方案即可
# 注意dfs中要将字典和队列重新赋值
import collections
class Solution:
def DFS(self,Data,Target):
# 习惯将Data转化为矩阵
self.dict = self.index2Cor(Data);
# 设置起点
s = '0;0'
# 存储方案
self.ways = []
# 目标
self.Target = Target
Flag = self.dfs(s,self.dict,0,[])
# print(dict)
return Flag
def dfs(self,start,dict,Sum,parent):
# 传递字典
new_dict = {}
for key in dict.keys():
if key != start: #去除已访问的节点
new_dict[key] = dict[key]
# 传递列表
new_parent = []
for i in parent:
new_parent.append(i)
## 算法处理
# 求和
Sum = Sum + self.dict[start][0]
# 加入列表
new_parent.append(start)
# 判断是否等于边长
if Sum == self.Target:
# 如果相等,则保存所有边
temp = []
for i in new_parent:
# # 去除字典中已经访问过的点
# new_dict.pop(i)
temp.append(i)
self.ways.append(temp)
# 清空Sum和parent
Sum = 0
new_parent = []
# 判断是否终止:只要有三个边满足,最后一个边也就满足了,不必再计算了
if len(self.ways) == 3:
return True
# 准备进入下一次循环
new_keys = new_dict.keys()
for key in new_keys:
if self.dfs(key,new_dict,Sum,new_parent):
return True
return False
def index2Cor(self,data):
# 设置字典
dict = collections.defaultdict(list)
length = len(data);
for i in range(length):
str1 = str(0)+";"+str(i)
dict[str1] = [int(data[i])]#这里写成[],便于后续索引
return dict
## 迎接输入
n = int(input().strip())
data = []
data_size = []
for i in range(n):
temp = list(map(str,input().strip().split(' ')))
data_size.append(int(temp[0]))
data.append(sorted(temp[1:],reverse=True)) # 降序排列
# print(data)
# print(data_size)
## 接下来,对每一批数据进行处理
for i in range(n):
size = 4
subData = data[i]
# 求和与边
Sum = 0
for i in subData:
Sum = Sum + int(i)
# #1 边不是整数,返回no
# #2 边小于最大值,返回no
if int(subData[0]) > int(Sum//size) or int(float(Sum/size)*size) != int(int(Sum/size)*size):
print("no")
else:
# 具体处理——dfs查找方案
#
target = int(Sum/size);
test = Solution()
ans = test.DFS(subData,target)
if ans:
print("yes")
else:
print("no")
输入:
3
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5
输出:
yes
no
yes