题目抽象:给你你一个整数数组,能否从中取出一些树,使得他们的和能被m整除。
分析:见代码注释。
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int MS = 1000005; 5 int n, m; 6 int cnt[MS], r[MS], tem[MS]; 7 int main() { 8 scanf("%d%d", &n, &m); 9 memset(cnt, 0, sizeof(cnt)); 10 for (int i = 0; i < n; i++) { 11 scanf("%d", &r[i]); 12 r[i] %= m; 13 cnt[r[i]]++; // 统计不同余数的个数 14 } 15 memset(r, 0, sizeof(r)); //初始化余数i不能构成 16 for (int i = 0; i < m; i++) { 17 if (cnt[i] > 0) { //处理余数i 18 int x = 1; 19 while (cnt[i] > 0) { 20 int y = x < cnt[i] ? x : cnt[i]; 21 cnt[i] -= y; 22 x *= 2; // 倍增算法处理。 23 int z = (i * y) % m; // y个余数i构成余数z. 24 for (int j = 0; j < m; j++) { 25 if (r[j]) 26 tem[(j + z) % m] = 1; // 在余数j的基础上构成余数(j + z) %m 27 } 28 for (int j = 0; j < m; j++) { 29 r[j] += tem[j]; // 更新能构成的余数 30 tem[j] = 0; 31 } 32 r[z] = 1; //余数z能构成 33 } 34 if (r[0] > 0) 35 break; 36 } 37 } 38 if (r[0] > 0) 39 printf("YES\n"); 40 else 41 printf("NO\n"); 42 return 0; 43 }
时间: 2024-10-06 14:27:32