[蓝桥杯 2020 省 B1] 整数拼接
题目描述
给定一个长度为
n
n
n 的数组
A
1
,
A
2
,
⋯
,
A
n
A_1,A_2,\cdots,A_n
A1,A2,⋯,An。你可以从中选出两个数
A
i
A_i
Ai 和
A
j
A_j
Aj(
i
≠
j
i\neq j
i=j),然后将
A
i
A_i
Ai 和
A
j
A_j
Aj 一前一后拼成一个新的整数。例如 12
和 345
可以拼成 12345
或 34512
。注意交换
A
i
A_i
Ai 和
A
j
A_j
Aj 的顺序总是被视为
2
2
2 种拼法,即便是
A
i
=
A
j
A_i=A_j
Ai=Aj 时。
请你计算有多少种拼法满足拼出的整数是 K K K 的倍数。
输入格式
第一行包含 2 2 2 个整数 n n n 和 K K K。
第二行包含 n n n 个整数 A 1 , A 2 , ⋯ , A n A_1,A_2,\cdots,A_n A1,A2,⋯,An。
输出格式
一个整数代表答案。
样例 #1
样例输入 #1
4 2
1 2 3 4
样例输出 #1
6
提示
对于所有评测用例, 1 ≤ n ≤ 1 0 5 1\le n\le10^5 1≤n≤105, 1 ≤ k ≤ 1 0 5 1\le k\le10^5 1≤k≤105, 1 ≤ A i ≤ 1 0 9 1\le A_i\le10^9 1≤Ai≤109。
蓝桥杯 2020 第一轮省赛 B 组 I 题。
优化方法
以空间换时间
代码
#include<iostream>
#include<string>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n, k;
int a[N], p[11][N];
LL sum;
int main() {
cin >> n >> k;
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
for (int i = 0; i < n; i++)
{
LL t = a[i] % k;
for (int j = 0; j < 11; j++) {
p[j][t]++;
t = t * 10 % k;
}
}
for (int i = 0; i < n; i++) {
int len = to_string(a[i]).size();
sum += p[len][(k - a[i] % k) % k];
LL t = a[i];
while (len--) t = t * 10 % k;
if ((t + a[i]) % k == 0) sum--;
}
cout << sum << endl;
return 0;
}