30 pts
M = 1不会做? 救不了你了.
M = 2我们只要先涂偶数的再涂奇数的就行了.
60 pts
我们先把3的倍数涂完, 之后轮流涂模3余1的和余2的.
最后把剩下的按顺序涂.
100 pts
先把4的倍数涂完.
之后把余2的涂偶数个.
然后把余1的和余3的组合涂
假如还剩下一个余2的, 就把这个余2的和余1、余3中多余的两个组合起来涂.
(你问我为什么会有多余的两个? 自己手动算一算啊)
最后把剩下的涂了.
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100000 + 5;
int kase, n, m, S, a[maxn], ans, p[5];
int main() {
freopen("diyiti.in", "r", stdin);
scanf("%d", &kase);
while(kase--) {
memset(p, 0, sizeof(p));
ans = 0;
scanf("%d%d%d", &n, &m, &S);
for(int i = 1; i <= S; ++i) {
scanf("%d", a+i);
p[a[i]%m]++;//p数组储存模m余i的数的数量
if(a[i] >= m) {//假设所有都能起到最大作用
ans += (a[i]/m*(m*2-1) - m + a[i]%m +
max(0, a[i]%m-1));
} else {
ans += a[i] - 1;
}
}
if(m == 3) {//减去被迫拆开的
if(p[2] > p[1])
ans -= (p[2]-p[1]) / 3;
} else if(m == 4) {
if(p[3] > p[1])
ans -= (p[3]-p[1]) / 2;
}
printf("%d\n", ans);
}
}