当前位置: 代码迷 >> 综合 >> HihoCoder - 1701【找规律】
  详细解决方案

HihoCoder - 1701【找规律】

热度:60   发布时间:2023-11-20 06:02:06.0

给定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

一个整数表示答案。

Sample Input
5 3 2  
1 2 3 4 5
Sample 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)