给定N个整数A1, A2, ... AN,小Hi希望从中选出M个整数,使得任意两个选出的整数的差都是K的倍数。
请你计算有多少种不同的选法。由于选法可能非常多,你只需要输出对1000000009取模的结果。
Input第一行包含三个整数N、M和K。
第二行包含N个整数A1, A2, ... AN。
对于30%的数据,2 ≤ M ≤ N ≤ 10
对于100%的数据,2 ≤ M ≤ N ≤ 100 1 ≤ K, Ai ≤ 100
Output一个整数表示答案。
5 3 2 1 2 3 4 5Sample Output
1
题解:设任意两个选出的整数为 a, b; K的倍数为c;即:a - b = cK;
对原式进行逐步变形:a = b + cK ----> a % K = b % k + (ck) % K ----> a % K == b % K;
所以规律就是当两个数分别对K取余的值相等,则满足a - b 的差是K的倍数;我们可以开个数组用来存储
对K取余的值相等的个数,然后算出组合数,求组合数可以根据 C(n,m)=C(n-1,m-1)+C(n-1,m)来打表;
#include<iostream>
using namespace std;
const int mod = 1000000009;
int M, N, K;
int a[105];
int b[105];
long long c[105][105];
int zhs()//打表
{for (int i = 1; i < 105; i++)c[i][0] = 1;c[1][1] = 1;for (int i = 2; i < 105; i++){for(int j = 1; j <= i; j++){c[i][j] = c[i - 1][j - 1] + c[i - 1][j] % mod;}}}
int main(){cin >> N >> M >> K;zhs();for (int i = 0; i < N; i++){cin >> a[i];b[a[i] % K]++;}long long ans = 0;for (int i = 0; i < 105; i++){if(b[i] >= M){long long tem = c[b[i]][M];ans = (ans + tem) % mod;}}printf("%d\n", ans % mod);
}
C(n,m)=C(n-1,m-1)+C(n-1,m)