标签:一个 col rod cout include 输入 return 分享 blank
原题地址:Timus[1091. Tmutarakan Exams]
输入一对整数K和S,求出由K个互不相等且不大于S的正整数组成的集合的个数N,当N大于10000时,输出10000即可。
想到的解法是去求各个质数的倍数所能组成的集合数,这个就是一个组合数。然后用集合元素个数的加法定理?cardinality of (A union B) = cardinality of (A) + cardinality of (B) - cardinality of (A intesect B)的这个。
用dfs来遍历可能的质数积的组合,代码如下:
#include <iostream> using namespace std; int K, S; const int MAX_N = 9; bool done; int primes[MAX_N] = { 2, 3, 5, 7, 11, 13, 17, 19, 23 }; int combinations(int k, int n) { if (2 * k > n) { k = n - k; } long long x = 1; int z = k; for (int i = 0; i < k; ++i) { x *= n - i; while (z > 1 && x % z == 0) { x /= z--; } } return x; } int ans = 0; void dfs(int k, int product, int m) { if (k + 1 != MAX_N && K * product * primes[k + 1] <= S) { dfs(k + 1, product, m); } product *= primes[k]; if (K * product > S) return; ++m; int c = combinations(K, S / product); if (c >= 10000) { ans = 10000; done = true; return; } ans += ((m & 1) ? 1 : -1) * c; if (ans >= 10000) { done = true; } if (!done && k + 1 != MAX_N && K * product * primes[k + 1] <= S) { dfs(k + 1, product, m); } } int solve() { done = false; dfs(0, 1, 0); if (done) return 10000; return ans; } int main() { cin >> K >> S; cout << solve() << endl; return 0; }
标签:一个 col rod cout include 输入 return 分享 blank
原文地址:https://www.cnblogs.com/knull/p/9973888.html