1 条题解
-
0
#include <bits/stdc++.h> using namespace std; int t; // [1] t-测试数据总组数 int arr[100100]; // [2] arr-存储所有器材价格的全局数组 // 计算长度为m的链的独立集数目 long long countChain(int m) { // [21] m-传入的当前链长度 if (m == 1) return 2; // [22] 边界判断:1个节点的独立集数 if (m == 2) return 3; // [23] 边界判断:2个节点的独立集数 long long a = 2, b = 3; // [24] a=f(m-2), b=f(m-1)-递推滚动变量 // [25] 从第3项开始递推求独立集数 for (int i = 3; i <= m; ++i) { long long c = a + b; // 计算当前项 a = b; // 滚动更新前前项 b = c; // 滚动更新前项 } return b; // 返回长度为m的链的独立集总数 } int main(){ cin >> t; // [3] 读取测试数据总组数 // [4] 循环处理每一组测试数据 while(t--) { int n , k; // [5] n-当前组器材总数,k-禁止的价格差 cin >> n >> k; // [6] 读取当前组的n和k // [7] 读取当前组n个器材的价格 for(int i = 1;i <=n ;i++) cin >> arr[i]; sort(arr + 1 , arr + n + 1); // [8] 对当前组价格数组升序排序 vector<vector<int>> dp(k); // [9] dp-按模k余数分组的二维容器 // [10] 将当前组所有器材按价格模k余数归类 for(int i = 1;i <=n ;i++) { int r = arr[i] % k; // [11] r-当前价格模k的余数 dp[r].push_back(arr[i]); // [12] 将价格放入对应余数的分组 } long long ans = 1; // [13] ans-当前组最终答案,初始化为1用于累乘 // [14] 遍历每个余数分组,计算总方案数 for(int i = 0;i < k ;i++) { if(dp[i].empty()) continue; // [15] 跳过无元素的空分组 int len = 1; // [16] len-当前连续链的长度 // [17] 遍历分组内元素,拆分出所有独立的链 for(int j = 1;j < dp[i].size() ;j++) { // [18] 相邻元素差为k,属于同一条链 if(dp[i][j] - dp[i][j-1] == k){ len++; // 链长加1 } // [19] 链断裂,计算前一段链的贡献 else{ ans *= countChain(len); // 累乘当前链的方案数 len = 1; // 重置链长为1 } } ans *= countChain(len); // [20] 累乘分组内最后一条链的方案数 } cout << ans << endl; // [26] 输出当前组的答案 } return 0; }
信息
- ID
- 1474
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者