刷Leetcode算法的第十三天

序言

这次刷拼多多编程的笔试题

题目:
小多想在美化一下自己的庄园。他的庄园毗邻一条小河,他希望在河边种一排树,共 M 棵。小多采购了 N 个品种的树,每个品种的数量是 Ai (树的总数量恰好为 M)。但是他希望任意两棵相邻的树不是同一品种的。小多请你帮忙设计一种满足要求的种树方案

输入解释:
第一行包含一个正整数 N,表示树的品种数量。
第二行包含 N 个正整数,第 i (1 <= i <= N) 个数表示第 i 个品种的树的数量。

输出要求:
输出一行,包含 M 个正整数,分别表示第 i 棵树的品种编号 (品种编号从1到 N)。若存在多种可行方案,则输出字典序最小的方案。若不存在满足条件的方案,则输出"-"。

例子如下:

输入:
3
4 2 1
输出:
1 2 1 2 1 3 1

思路:
首先要知道 当某一类树剩余数量大于总数M的一半是不可能有满足条件的方案的
然后,这是个不断剪枝的问题


########################
#由于python 默认递归深度不超过1000,做dfs会比C吃亏
#受限于python默认的最大递归深度,会出现某些数据爆函数栈的问题,而同样的算法使用C++则不会有问题
#手动修改深度  
import sys
sys.setrecursionlimit(10000000)
########################  

classes = map(int, input().strip().split())                #树的品种
list_class_num = list(map(int, input().strip().split()))   #第 i 个品种的树的数量
M = sum(class_num)                                         #总长度 
ans = []

def dfs(list_C_N, M, prev):
	"""
	list_C_N: 代表list_class_num
	M:总长度
	prev: 录入答案时的树的种类,先给个初始值是0
	"""
	####################
	##当循环到M总长度为0的时候,这个时候可以停止了
	if M == 0:
		return True 
	####################
	
	####################
	#某一类树剩余数量大于总数M的一半是不可能有满足条件的方案的 
    for i in range(len(list_C_N)):
        if list_C_N[i]*2 > M+1: 
            return False 
    ####################
    
    ####################
    #递进
    for i in range(len(list_C_N)):
    	current = i+1
    	if list_C_N[i] > 0 and prev != current:
    		list_C_N[i] -= 1 
    		ans.append(current)
    		#开始进入循环
    		if dfs(list_C_N, M-1, current):
    			return True 
    		ans.pop(-1) # 不满足则回退
    		list_C_N[i] += 1
    return False
    ####################
    
print(" ".join(map(str, ans)) if dfs(list_C_N, M, 0) else "-") 

题目二:

给定一个长度为偶数的数组arr,将该数组中的数字两两配对并求和,在这些和中选出最大和最小值,请问该如何两两配对,才能让最大值和最小值的差值最小

一共2行输入。
第一行为一个整数n
第二行为n个数,组成目标数组,每个数大于等于2,小于等于100。
输出最小的差值。

例子如下:

输入:
4
2 6 4 3
输出:
1 

用直接发会导致时间超时
所以,先把序列按大小拍好,然后来一个首尾相加,,再用按大小排好,再首尾相减
代码如下:

n = map(int, input())
lis = list(map(int, input().split()))
#按从小到大排序
lis.sort()
sum_ = []
for i in range(len(lis)//2):
	sum_.append(lis[i]+lis[-i-1])
sum_.sort()
print(abs(sum_[-1]-sum_[0]))

题目三:

你在玩一个回合制角色扮演的游戏。现在你在准备一个策略,以便在最短的回合内击败敌方角色。在战斗开始时,敌人拥有HP格血量。当血量小于等于0时,敌人死去。一个缺乏经验的玩家可能简单地尝试每个回合都攻击。但是你知道辅助技能的重要性。
在你的每个回合开始时你可以选择以下两个动作之一:聚力或者攻击。
聚力会提高你下个回合攻击的伤害。
攻击会对敌人造成一定量的伤害。如果你上个回合使用了聚力,那这次攻击会对敌人造成buffedAttack点伤害。否则,会造成normalAttack点伤害。
给出血量HP和不同攻击的伤害,buffedAttack和normalAttack,返回你能杀死敌人的最小回合数

例子:

输入:
13
3
5
输出:
5

思路是:
当buffed attack 大于 两倍的 normal attack,这时 前面都用buffed比较快 只要比较剩余的量是否小于normal,要是小于,则最后一次使用normal attack
当buffed attack 小于 两倍的 normal attack,则这时候 直接都用normal attack
代码如下:

HP = int(input())
normal =  int(input())
buffed = int(input())
count = 0 
if buffed <= 2*normal: 
    count = HP//normal
    left = HP%normal
    if left==0:
        count += 0 
    else: 
        count += 1 
    
if buffed > 2* normal: 
    count = (HP//buffed)*2 
    left = HP%buffed 
    if left == 0:
        count += 0 
    elif left <= normal: 
        count +=  1
    elif left > normal: 
        count += 2 
print(count)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianafeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值