题解:
如果是暴力做法的话,肯定是两个循环遍历一下就行,时间复杂度是O(n^2),但是就这道题而言肯定会超时。
要想计算出有多少种拼法满足两个整数拼出的整数是k的倍数,必须遍历到每一个数,即外层循环必不可少,那如何将内层循环O(n)降下来呢。先将表达式写出来,假如找到两个数Ai和Aj,那么拼出来的数就是Ai*(10^(len(Aj))+Aj,例如12和345拼起来就是12*(10^3)+345,它的余数(Ai*(10^(len(Aj))+Aj)%k就等于((Ai%k*(10^len(Aj)%k))%k + Aj%k)%k. (len(Aj)表示Aj这个数的长度)
先看前面一项,(Ai%k*(10^len(Aj)%k))%k,由数据范围可知,len(Aj)的长度必然是大于等于1,小于等于10的,而对k取余后,余数肯定小于k的范围,因此数据允许,我们可以建立一张表,用来存放Ai乘10的不同次方(从1到10即可)对k取余的结果的个数,即b[r][(Ai%k*(10^r%k))%k],可知,第一个中括号的r范围是1-10,第二个中括号的范围是小于0-k。
再看第二项Aj%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],证明满足了题目条件,ans++就行。
时间复杂度分析:solve函数外层循环n,内层循环10,log10函数的复杂度为log10(Ai)=9.所以个人