牛客周赛 Round 7
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)

浙公网安备 33010602011771号