题目链接
https://www.dotcpp.com/oj/problem2578.html
题解链接
https://blog.csdn.net/qq_45328552/article/details/108345989
我的理解:
本来我是直接两层暴力直接写的,毫无疑问肯定会超时,但是考试的时候想不起来其他写法的时候,暴力还是能骗到一些分数的
至于思路的话这个链接里已经讲的很清楚了
在这里来记录一下我自己觉得不容易理解的point或者涉及的知识
求整数的长度
int length(double n)
{
return (int)log10(n)+1;//直接用这个公式就好 这样就不用转换成字符串在计算长度了
}
b数组的用处
b数组里面放的是0~10次方 a[i]*(10^j)%k的余数 的个数
那么对于((Ai%k*(10^len(Aj)%k))%k + Aj%k)%k=0,第一项和第二项的和一定是k(因为两者都小于k),k-Aj%k=(Ai%k*(10^len(Aj)%k))%k,我们如果在上面的表中找到b[len(Aj)][k-Aj%k],证明满足了题目条件
(设(Ai%k*(10^len(Aj)%k))%k为Q 那么利用b数组里存的就是0~10次方 余数为Q的个数(对应的是不同的a[i]) 那么我的a[j]就可以和这些个a[j]拼接来满足条件)
调用两次solve()的原因
第一遍solve的时候是默认i < j,拼接的顺序是A[i]A[j]组合,因此需要反转一下,从后往前再算一遍。
总结
暴力超时的时候,试着去分析一下条件,变换一下公式并分析,以此来转换代码思路
但其实我觉得还是很难想到的,反正我是想不出来,还是需要多做题,积累做题经验