众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。
输入格式
从标准输入读入数据。
第一行包括 2 个正整数 n, K。
第二行 n 个正整数,代表给定的 n 个数。
输出格式
输出到标准输出。
输出一行一个整数代表所求的和。
样例入
4 3 1 2 3 4
样例输出
9
样例说明
选择2、3、4。
数据约定
对于 30% 的数据,
n
<
=
100
n <= 100
n<=100。
对于 60% 的数据,
n
<
=
1000
n <= 1000
n <=1000。
对于另外 20% 的数据,
K
<
=
10
K <= 10
K <=10。
对于 100% 的数据,
1
<
=
n
<
=
1
0
5
,
1
<
=
K
<
=
1
0
3
1 <= n <= 10^5, 1 <= K <= 10^3
1<=n <=105, 1<=K <=103,给定的 n 个数均不超过
1
0
8
10^8
108。
暴力+优化纯粹的三重循环肯定是过不了的,所以需要优化,不过还是暴力的板子优化暴力法的几个方面:减少循环层数;二分;缩小搜索范围;做一些预处理,以空间换时间。这道题中可以先做一些预处理,用空间换时间,然后以此来减少循环次数,做到优化,其实从后往前看的话,这道题在做一方面优化的同时,也一起做了其他方面的优化,比如还缩小了搜索范围。这道题是求三个数的和是某个数的倍数,而不是等于那个数,那就要用到取模方面的知识了根据题意,我们要找
a
,
b
,
c
a,b,c
a,b,c 使得:
(
a
+
b
+
c
)
m
o
d
k
=
0
(a+b+c) mod k=0
(a+b+c) mod k=0而由模运算的知识可知,上面的式子等价于:
(
a
m
o
d
k
+
b
m
o
d
k
+
c
m
o
d
k
)
m
o
d
k
=
0
(a mod k+b mod k+c mod k) mod k=0
(a mod k+b mod k+c mod k) mod k=0这样便可以减少一重循环:利用
a
a
a 和
b
b
b 将
c
c
c 确定下来,就可以从三重循环降到二重循环做一个预处理,把输入的
n
n
n 个数按照余数分类,余数为0的放在一个集合中,为1的放在一个集合中……,这个过程可以用一个二维数组实现,而且还可以加一个限制条件,即我们只需要3个数的和,所以每个余数的集合里面维护三个数即可,并且要这些和最大,那么就维护最大的三个数令
r
1
=
a
m
o
d
k
r_1=a mod k
r1=a mod k;
r
2
=
b
m
o
d
k
r_2=b mod k
r2=b mod k;
r
3
=
c
m
o
d
k
r_3=c mod k
r3=c mod k,如果
r
1
+
r
2
+
r
3
r_1+r_2+r_3
r1+r2+r3 是
k
k
k 的倍数的话,那么就是符合题意的我们知道:
r
1
,
r
2
,
r
3
<
k
r_1,r_2,r_3C++用多了,复习一下C语言#include



