P8712 [蓝桥杯 2020 省 B1] 整数拼接
题意简述
给出
注意
拼接的顺序不同算不同的方案,即使
时间复杂度分析
得
在第
本题步骤
-
枚举整体数组来预处理
s 数组。 -
再依次枚举这个数组中的每个数
A_i 。然后在上述预处理之后的数组中找出一个或多个数字,这一个或多个数字A_j 满足A_j \times 10^ {k_i} ==-A_i \bmod k 。 -
其中每次算结果的时候需要判重。因为之前在计算预处理数组时候一定会枚举到自身,并将自身
\times 10 的j 次方\bmod k 存入到s 数组中。因此在这次计算结果的时候一定就要判断有无自己,有则结果减1 。
一些细节
利用 res += s[len][(k - t) % k] 得到数学中的余数,例如在 C++ 中
如果我们想得到余数 (k - t) % k,实现
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
//用a数组存储每个数 k只有10^5 开一个数组当作哈希表即可
int a[N], s[11][N];
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
//枚举每个数 预处理哈希表
for (int i = 0; i < n; i ++ )
{
LL t = a[i] % m;
//枚举当前数在每种指数下%k的余数是多少
for (int j = 0; j < 11; j ++ )
{
//第j个哈希表的余数是t
s[j][t] ++ ;
//幂次*10
t = t * 10 % m;
}
}
LL res = 0;
for (int i = 0; i < n; i ++ )
{
LL t = a[i] % m;
//求出ai的位数
int len = to_string(a[i]).size();
//位数为len 在第len个哈希表中查找有多少个 Aj 满足 Aj × 10^ki % k 的余数等于 -Ai
res += s[len][(m - t) % m];
//余数为(m - t) % m
LL r = t;
//判断Ai本身是否也在统计的范围内-> 计算 Ai × 10^ki % k 是否等于 Ai
while (len -- ) r = r * 10 % m;
//满足说明计算重复需要-1
if (r == (m - t) % m) res -- ;
}
printf("%lld\n", res);
return 0;
}