题目
cfhttps://codeforces.com/problemset/problem/1759/D
洛谷https://www.luogu.com.cn/problem/CF1759D
题目大意
给两个数n,m,求0后缀最长的最大的n*x,x<=m。
如果所有n*x都没有0后缀,输出n*m。
思路
假设n*x为0后缀最长的某个组合,那么n*x*k的0后缀一定不小于n*x 。
任意的10有10=2*5,n*x的所有0后缀由n和x中的2、5组成。
贪心的另n*x的2、5组合最多即可。
首先求n中的2和5因子的个数,再将多出来的部分用x补全,如果m中还有余下的2、5组合(也就是10),再将其加入x。
最后补上k=m/x 。
答案为 n*x*k 。
代码
void solve(){
int n,m;
cin >> n >> m;
int t = n;
int n2 = 0, n5 = 0;
while(t % 2 == 0) {
t /= 2;
n2++;
}
while(t % 5 == 0) {
t /= 5;
n5++;
}
ll d = 1;
while(n2 < n5 && d * 2 <= m) d *= 2, n2 ++;
while(n5 < n2 && d * 5 <= m) d *= 5, n5 ++;
while(d * 10 <= m) d *= 10;
int k = m / d;
cout << n*k*d << endl;
}
反思
该题分两步:
1) 将n*x中的10因子最大化
2) 将n*x最大化
题目中0后缀即10因子的体现。
经验总结
对于题干中有出现数的因子的题目,先在因子层面考虑。