整数拼接
整数拼接
给定一个长度为 $n$ 的数组 $A_{1},A_{2}, \dots ,A_{n}$。
你可以从中选出两个数 $A_{i}$ 和 $A_{j}$ ($i$ 不等于 $j$),然后将 $A_{i}$ 和 $A_{j}$ 一前一后拼成一个新的整数。
例如 $12$ 和 $345$ 可以拼成 $12345$ 或 $34512$。
注意交换 $A_{i}$ 和 $A_{j}$ 的顺序总是被视为 $2$ 种拼法,即便是 $A_{i}=A_{j}$ 时。
请你计算有多少种拼法满足拼出的整数是 $K$ 的倍数。
输入格式
第一行包含 $2$ 个整数 $n$ 和 $K$。
第二行包含 $n$ 个整数 $A_{1},A_{2}, \dots ,A_{n}$。
输出格式
一个整数代表答案。
$1 \leq n \leq {10}^{5}$,
$1 \leq K \leq {10}^{5}$,
$1 \leq A_{i} \leq {10}^{9}$
输入样例:
4 2 1 2 3 4
输出样例:
6
解题思路
很容易想到两个数两个数去枚举,但这样的时间复杂度是$O \left( n^{2} \right)$的,因此需要进行优化。
我们任意选择两个数$x$,$y$,对其进行拼接,得到$x \times {10}^{s} + y$,其中$s = len \left( y \right)$,即数字$y$的位数。我们要找的是有多个这样形式的数,满足$x \times {10}^{s} + y \equiv 0 ~ \left( mod~K \right) $。
我们可以通过枚举每一个数,把这个数当作上式的$y$,这时$y$和$s$都是一个确定的值,只需查看有多少个$x$,满足$x \times {10}^{s} + y \equiv 0 ~ \left( mod~K \right) $,进行一下变化,即有多少个$x$满足$x \times {10}^{s} \equiv -y ~ \left( mod~K \right) $。
我们可以进行预处理,用哈希表来统计每一个数乘上${10}^{n}$后模$K$得到的余数的次数。这里$n = 1, 2, \dots , 10$,每一个数都要取。原理是开$10$个哈希表,然后用第$n$个哈希表来统计每个数乘上${10}^{n}$后模$K$得到的余数的次数。
预处理完后,当再枚举每一个数$y$时,我们就可以直接查第$len \left( y \right)$个哈希表,查看有多少个数乘上$10$的$len \left( y \right)$次方后,$mod ~ K$后是$-y$的(当然,这里要转换为非负的余数)。
当然,如果$y$这个数乘上$10$的$len \left( y \right)$次方模$K$等于$-y$,即$y \times {10}^{s} + y \equiv 0 ~ \left( mod~K \right) $,那么我们的结果要减去一个$1$,因为在预处理的时候,我们是把这种情况也统计进去的。
AC代码如下:
1 #include <cstdio> 2 #include <string> 3 #include <algorithm> 4 using namespace std; 5 6 typedef long long LL; 7 8 const int N = 1e5 + 10; 9 10 int a[N], cnt[15][N]; 11 12 int main() { 13 int n, m; 14 scanf("%d %d", &n, &m); 15 for (int i = 0; i < n; i++) { 16 scanf("%d", a + i); 17 18 LL t = a[i] % m; 19 for (int i = 1; i <= 10; i++) { 20 t = t * 10 % m; 21 cnt[i][t]++; // 统计得到每个数的余数的次数 22 } 23 } 24 25 LL ret = 0; 26 for (int i = 0; i < n; i++) { 27 int len = to_string(a[i]).size(); 28 ret += cnt[len][(-a[i] % m + m) % m]; 29 30 LL t = a[i] % m; 31 while (len--) { 32 t = t * 10 % m; 33 } 34 if (t == (-a[i] % m + m) % m) ret--; // 除去这个数本身进行拼接的次数 35 } 36 37 printf("%lld", ret); 38 39 return 0; 40 }
参考资料
AcWing 2068. 整数拼接(蓝桥杯C++ AB组辅导课):https://www.acwing.com/video/2024/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16039875.html