《数据结构与算法分析python版》第六周编程作业

《数据结构与算法分析python版》第六周编程作业

1、铺瓷砖

题目内容:

给定一个长度为N的区域,及4种不同长度的瓷砖:灰瓷砖(长为1格)、红瓷砖(长为2格)、绿瓷砖(长为3格)与蓝瓷砖(长为4格),求所有不同的铺满整个区域的方法数。

例如:当N=5时,共有15种铺满区域的方法,示意图如下:
《数据结构与算法分析python版》第六周编程作业_第1张图片

输入格式:

一个自然数N

输出格式:

一行数字,表示不同的方法总数
5

输出样例:

15

思路分析:

1、整个过程其实是容易想到的。无非就是一种一种铺,铺满为止。拿3举例:
《数据结构与算法分析python版》第六周编程作业_第2张图片
所以基础的递归过程就是:循环1-4类瓷砖,一片片的自我调用,最后把区域占完。
但是这样就出现一个递归中很普遍的问题,无用的计算太多,所以这里考虑建立查询表,把前面的结果给利用起来。
所以进一步去分析发现:
《数据结构与算法分析python版》第六周编程作业_第3张图片
最后结果有点尴尬:按自己的测试情况1-100完全可以轻松输出。但是慕课评分显示用例2出现了错误。求指点。

脚本:

def puman(N):
    result_lst = [0]*(N+1)

    def base(n):
        add_1 = 0
        if n == 0:
            return 1
        elif n < 0:
            return  0
        count = 0
        for i in range(1,5):
            add_1 = base(n-i)
            count = count +add_1            
        return count
        
    for j in range(1,N+1):

        if j <= 5:
            result_lst[j] = base(j)
        else:
            result_lst[j] = 2*result_lst[j-1] - result_lst[j-5]
            # print(result_lst) #可以输出查询表
  return result_lst[N]
  
N = int(input())
print(puman(N))

2、分发糖果

题目内容:

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。
相邻的孩子中,评分高的孩子必须获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?

输入格式:

一个列表,以文本格式的有效Python表达式给出

输出格式:

一行数字,表示满足分配条件所需的最少糖果数

输入样例:

[1,2,2]

输出样例:

4

注:可行的分配方案为1、2、1 颗糖果;第三个孩子只得到1颗糖果也满足题目条件
解题思路:
《数据结构与算法分析python版》第六周编程作业_第4张图片
还是大佬思路清奇啊,请查看大佬原代码
这里单纯做个图方便理解。
硬性条件是,只要旁边有比你小的你就一定要比那个数字小的拿的糖果多。所以一路比过去,只要有确确实实大的,多拿糖果就完事儿了。

def candy(ratings):
    sum = 0
    n = len(ratings)
    count_lst = [1]*n

    for i in range(1,n):
        if ratings[i] > ratings[i-1]:
            count_lst[i] = count_lst[i-1] + 1
    for i in range(n-2, -1, -1):
        if ratings[i] > ratings[i+1] and count_lst[i] <= count_lst[i+1]:
            count_lst[i] = count_lst[i+1] + 1
    for i in range(n):
        sum += count_lst[i]
    # print(count_lst)
    return sum

lst = eval(input())
print(candy(lst))

3、表达式按不同顺序求值

题目内容:

给定一个表达式字符串,求出按不同的求值顺序可能得到的所有结果

输入格式:

一行字符串,仅包含0-9与运算符+、-与*

注:字符串保证三种运算符左右均为数字字符

输出格式:

所有不重复的可能的结果,从小到大排序并以半角逗号","分隔

输入样例:

2 * 3 - 4 * 5

输出样例:

-34,-14,-10,10

注:

(2*(3-(4*5))) = -34

((2 * 3)-(4 * 5)) = -14

((2*(3-4))*5) = -10

(2*((3-4)*5)) = -10

(((2*3)-4)*5) = 10

思路捋一捋:

这个题就很尴尬了,切入点不对,一开始想着直接对运算法做一个排列组合。然后根据运算符的顺序,带入数值逐步求解。但是在第一步排列组合就卡住了,后来看了下别人的思路,发现确实这个切入点不行。但是这实现过程中遇到一些问题还是能帮助理解递归的。所以先放一下思路图,以后再想想。
《数据结构与算法分析python版》第六周编程作业_第5张图片
然后就是查到的这道题的一个主流的做法,代码略有却别,但是处理思路是一样的。
不过个人感觉也是不太好想。这个递归函数的位置也比价新颖。认认真真从思路顺推算法,再从演算算法过程理解思路。还是很有收获的。

递归过程分析:

《数据结构与算法分析python版》第六周编程作业_第6张图片
这里其实就是把等式分成两部分,然后分别求值。对于分后的两部分依然可以继续划分。由此最后可以化简为最简单的两数运算。

然后就得到了脚本

def findWays(expr):
    # 用于将字符串转为数字与运算符,供参考
    nums, ops = [], []
    num = 0
    for c in expr:
        if '0' <= c <= '9':
            num = num * 10 + ord(c) - 48
        else:
            ops.append(c)
            nums.append(num)
            num = 0
    else:
        nums.append(num)


    def oper(number1, number2, operand):
        opers = '+-*'
        if operand == opers[0]:
            return number1 + number2
        elif operand == opers[1]:
            return number1 - number2
        elif operand == opers[2]:
            return number1 * number2

    def calc(low, high):
        if low == high:
            return [nums[low]]
        temp = []
        for i in range(low, high):

            for a in calc(low, i):
                for b in calc(i + 1, high):

                    temp.append(oper(a,b,ops[i]))
                    # print(a,b,temp)
        return temp
    res = calc(0, len(nums)-1)
    res = list(set(res))
    res.sort()
    res = [str(i) for i in res]
    return ','.join(res)

expr=input()
print(findWays(expr))

为了方便理解,这里做了比较细致的带入演算。精巧的很

《数据结构与算法分析python版》第六周编程作业_第7张图片

你可能感兴趣的:(《数据结构与算法分析python版》第六周编程作业)