POJ-1011 Sticks + Python(DFS)

题目链接:

# https://www.cnblogs.com/dongsheng/archive/2012/08/14/2638926.html

一 注意

1. 当前题目与前一篇POJ 2362 - Square + Python_xxdragon126的博客-CSDN博客

的核心算法一模一样,因此,直接使用的上一篇的核心代码,仅将输入环节做了修改。

2. 修改内容包括:

        2.1 题目可转化为:如何对一组数据进行等分,并要求等分的份数最大,即每一份的长度最小。

        2.2 已知,一组数据有subSize个元素,因此可以设置一个循环,依次假设一组数据可以进行subSize等份,并依次减小该等份数值,直到找到第一个可行的等分方案。

二 代码

# POJ-1011 Sticks
# https://www.cnblogs.com/dongsheng/archive/2012/08/14/2638926.html

# 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 = []
            # 判断是否终止:只要有size-1个边满足,最后一个边也就满足了,不必再计算了
            if len(self.ways) == size-1:
                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



## 迎接输入
data_size = []
data = []
while True:
    n = int(input().strip())
    if n == 0:
        break
    else:
        data_size.append(n)
    temp = list(map(str,input().strip().split(' ')))
    data.append(sorted(temp,reverse=True)) # 降序排列
print(data_size)
print(data)
##
n = len(data_size)
for i in range(n):
    # 取出数据
    subData = data[i]
    # 取出size
    subSize = data_size[i]
    # 求和与边
    Sum = 0
    for i in subData:
        Sum = Sum + int(i)
    # 开始处理吧——依次将size变小,直到能够获得“等边数据”
    for size in range(subSize,1,-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")
            continue
        else:
            # 具体处理——dfs查找方案
            #
            target = int(Sum / size);
            test = Solution()
            ans = test.DFS(subData, target)
            if ans:
                print(str(target))
                break # 只要有一种方案可行,那么就结束当前循环
        #     else:
        #         print("no")



输入:

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

输出:

6
5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值