牛客周賽 Round 7

udiandianis發表於2024-06-03

D 遊遊的選數乘積

題目描述

遊遊拿到了一個陣列,她準備在其中選擇兩個數,使得乘積的末尾至少有\(x\)個0。遊遊想知道,至少有多少種不同的取數方法?

輸入描述

第一行輸入兩個正整數\(n\)\(x\),代表陣列的大小以及乘積末尾\(0\)的數量。
第二行輸入\(n\)個正整數\(a_i\),代表遊遊拿到的陣列。
\(1\leq n,x \leq 10^5\)
\(1\leq a_i \leq 10^9\)

輸出描述

輸出一個整數,代表遊遊選擇的方案數。

解題思路

數字末尾的0顯然只能由2和5相乘得到,又因為1e9範圍內,最多13個5,30個2,因此可以用計數dp解決。
建立一個二維陣列dp,對於每一個數字都記錄數字其2與5因子數量,最後列舉所有可能的兩陣列合並累加滿足條件的數字數量。

程式碼實現

n,x=map(int,input().split())
a=list(map(int,input().split()))
ans=0
#dp[i][j]表示有多少個數的2的因子數量為i且5的因子數量為j
dp=[[0]*13 for _ in range(30)]#2**30>1e9 5**13>1e9
for i in range(n):
    cnt2=cnt5=0
    while a[i]%2==0:
        a[i]//=2
        cnt2+=1
    while a[i]%5==0:
        a[i]//=5
        cnt5+=1
    for i in range(max(0,x-cnt2),30):#2的因子
        ans+=sum(dp[i][max(0,x-cnt5):])#5的因子
    dp[cnt2][cnt5]+=1
print(ans)