首页 > 试题广场 >

小美的区间删除

[编程题]小美的区间删除
  • 热度指数:4056 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小美拿到了一个大小为n的数组,她希望删除一个区间后,使得剩余所有元素的乘积末尾至少有k个 0。小美想知道,一共有多少种不同的删除方案?

输入描述:
第一行输入两个正整数n,k
第二行输入n个正整数a_i,代表小美拿到的数组。
1\leq n,k \leq 10^5
1\leq a_i \leq 10^9


输出描述:
一个整数,代表删除的方案数。
示例1

输入

5 2
2 5 3 4 20

输出

4

说明

第一个方案,删除[3]。
第二个方案,删除[4]。
第三个方案,删除[3,4]。
第四个方案,删除[2]。
import re
import sys
readline = 0

def get_res(array,zero_num):
    array25 = []
    for a in array:
        array25.append([get_2num(a),get_5num(a)])
    all_2num = sum(a[0] for a in array25)-zero_num
    all_5num = sum(a[1] for a in array25)-zero_num
    if all_2num<0 or all_5num<0:
        return 0
    res = 0
    temp = []

    for a in array25:
        temp.append(a)
        all_2num = all_2num-a[0]
        all_5num = all_5num-a[1]
        while all_2num<0 or all_5num<0:
            q = temp.pop(0)
            all_2num = all_2num+q[0]
            all_5num = all_5num+q[1]
        res = res+len(temp)
    return res

    
def get_2num(num):
    a = 0
    while num%2==0:
        num = num/2
        a = a+1
    return a

def get_5num(num):
    a = 0
    while num%5==0:
        num = num/5
        a = a+1
    return a
zero_num=0
try:
    while True:
        line = sys.stdin.readline().strip()
        if line == '':
            break
        readline = readline+1
        lines = line.split()
        if readline==1:
            zero_num = int(lines[1])
        if readline==2:
            array = [int(a) for a in lines]
            print(get_res(array,zero_num))
        
except:
    pass
不知道为什么超时了,应该没有优化的点了吧
发表于 2025-04-19 12:39:11 回复(1)
获取因数 2和5
构建前缀和
滑动窗口求解。
import sys

def count_factor(num, factor):
    cnt = 0
    while num % factor == 0:
        cnt += 1
        num = num // factor
    return cnt

def main():
    n, k = map(int, sys.stdin.readline().split())
    arr = list(map(int, sys.stdin.readline().split()))
    
    two = []
    five = []
    for num in arr:
        two.append(count_factor(num, 2))
        five.append(count_factor(num, 5))
    
    pre_two = [0] * (n + 1)
    pre_five = [0] * (n + 1)
    for i in range(n):
        pre_two[i + 1] = pre_two[i] + two[i]
        pre_five[i + 1] = pre_five[i] + five[i]
    
    sum2 = pre_two[n]
    sum5 = pre_five[n]
    
    target2 = sum2 - k
    target5 = sum5 - k
    
    if target2 < 0&nbs***bsp;target5 < 0:
        print(0)
        return
    
    res = 0
    l = 0
    for r in range(1, n + 1):
        while l < r and (pre_two[r] - pre_two[l] > target2&nbs***bsp;pre_five[r] - pre_five[l] > target5):
            l += 1
        res += r - l
    
    print(res)

if __name__ == "__main__":
    main()


发表于 2025-03-09 12:58:49 回复(0)
这里直接两层for循环找删除区间,然后得到剩下元素,通过求解剩下元素的和,然后判断某未有几个0。但是有些案例测试不通过,大佬们可以提示一下问题在哪里啊?
import math
ins=[]
while True:
    try:
        ins.append(list(input().split()))
    except:
        break

N=int(ins[0][0])
k=int(ins[0][1])
data=[int(_) for _ in ins[1]]

cnt = 0
for i in range(N):
    for j in range(i+1,N):#
        #if len(data[i:j]) >= 1 and len(data[0:i]+data[j:]) <= N-1 and len(data[0:i]+data[j:]) >= 1:
        if True:
            '''
            val1=math.prod(data[0:i])
            val2=math.prod(data[j:])
            val = str(val1*val2)
            '''
            #print ('data=',data,'删除',data[i:j],'剩余',data[0:i]+data[j:])
            val=str(math.prod(data[0:i]+data[j:]))
            '''
            val = 1
            for _ in data[0:i]+data[j:]:
                val = val*_
            '''
            val = str(val)

            n0 = 0
            for t in range(len(val)):
                if val[-(t+1)] == '0':
                    n0 += 1
                else:
                    continue
            #print ('n0=',n0,'k=',k)
            if n0 >= k:
                cnt += 1

print (cnt)
发表于 2024-08-22 10:23:42 回复(1)
n, k = map(int, input().split())
li = list(map(int, input().split()))
numli = []

for x in li:
    t = x
    a = b = 0
    while t % 2 == 0&nbs***bsp;t % 5 == 0:
        if t % 2 == 0:
            t //= 2
            a += 1
        if t % 5 == 0:
            b += 1
            t //= 5
    numli.append((a, b))
# print(numli)
sm2 = [0] * (n + 1) # 求2的数量的前缀和
sm5 = [0] * (n + 1)
for i in range(1, n + 1):
    sm2[i] = sm2[i - 1] + numli[i - 1][0]
    sm5[i] = sm5[i - 1] + numli[i - 1][1]

# print(sm2)
# print(sm5)

i= 0
j = 0
res = 0
while i < n + 1:
    while j < n + 1:
        a2 = sm2[-1] - sm2[j] + sm2[i]
        a5 = sm5[-1] - sm5[j] + sm5[i]
        if min(a2, a5) < k:
            break
        j += 1
    if i >= j:
        break
    res += j - 1 - i
    i += 1
print(res)
    

    

发表于 2024-03-14 08:24:23 回复(2)