POJ 2362 - Square + Python(DFS)

该博客详细介绍了如何使用深度优先搜索(DFS)解决POJ2362问题,即寻找能够构成正方形的边。博主强调了在递归过程中处理字典和队列时的注意事项,如需复制字典和列表,以及在转换数据为矩阵时的索引技巧。此外,还展示了具体的DFS代码实现,包括目标和终止条件的设定,以及输入数据的处理步骤。文章最后给出了多个测试用例及其输出结果。
摘要由CSDN通过智能技术生成

原题链接:

# 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值