积木(两种解法)

Posted WINNER_QIUQIU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了积木(两种解法)相关的知识,希望对你有一定的参考价值。

题目

n n n堆积木,已知第 i i i堆积木有 h i h_i hi块且有一个容量无限的包。现进行搭积木操作,要求搭好积木后每堆积木的数目为严格递增的,考虑在不同情况下能否实现。每次可进行的操作如下:
(1)从包里掏出一块积木放在当前一堆;
(2)从当前积木堆中拿出一块积木放进包里;
(3)走到下一堆积木(不可以往回走)。

分析

由于在一堆积木前可重复可进行操作且包的容量是无限的,为了使积木堆的数量是严格递增的,因此要使排在前面的积木堆中积木数量尽可能的少。换句话说,应该使第一堆积木数量为0,第二堆为1,第三堆为2…以此类推。那么到第 i i i堆所需积木的最少数目应该为 i ( i − 1 ) / 2 i(i-1)/2 i(i1)/2个。
方法一:判断第1堆到第 i i i堆每一堆都满足上述条件

print("请输入组数:")
T = int(input())
for k in range(T):    
    a = 0#用来记录积木堆中积木的个数    
    print("积木堆数与包中积木的个数:")    
    n,m = list(map(int,input().split()))#用于记录n和m   
    list2 = []    
    block = 1#用于判断    
    print("请输入每堆积木的个数:")    
    list2 = list(map(int,input().split()))    
    for i in range(n):        
        a = 0        
        for j in range(i+1):            
            a = a+int(list2[j])        
        if a+m<i*(i+1)/2:            
            block=0            
            break    
    if(block):        
        print("YES")    
    else:        
        print("NO")

第一种方法思想比较直接,但用到了两层循环,大大的减少了运行的效率。
方法二:判断包中积木的数量是否大于第 i + 1 i+1 i+1堆积木超过第 i i i堆积木所需数目

T = int(input())
for k in range(T):    
    n,m = list(map(int,input().split()))    
    list1 = list(map(int,input().split()))    
    block = 1    
    for i in range(n):        
        if m<i-list1[i]:            
            block = 0            
            break        
        m += list1[i]-i    
    if flag:        
        print("YES")    
    else:        
        print("NO")

描述:
第一行数据组数T
对于每组数据,第一行数值n,m,接下来一行 n n n个数字表示 h i h_i hi
1 ≤ n ≤ 100000 , 0 ≤ h i ≤ 1 0 9 , 1 ≤ T ≤ 10 , 0 ≤ m ≤ 1 0 9 \\leq n\\leq 100000,0\\leq h_i\\leq 10^9,1\\leq T\\leq 10,0\\leq m\\leq 10^9 n100000,0hi109,1T10,0m109
算例一:
输入:
2
5 3 #n,m
2 2 3 3 1
5 2 #第二组n,m
0 0 1 2 1
输出:
YES
NO
算例二:
输入:
1
10 3
1 8 4 3 10 6 8 5 4 1
输出:
YES

以上是关于积木(两种解法)的主要内容,如果未能解决你的问题,请参考以下文章

搭积木

搭积木(java)-蓝桥杯

搭积木 并查集

放积木

P2342 叠积木

LQ0051 搭积木枚举