Timus[1091. Tmutarakan Exams]

Posted knull

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Timus[1091. Tmutarakan Exams]相关的知识,希望对你有一定的参考价值。

原题地址: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;
}
Solution.

 

以上是关于Timus[1091. Tmutarakan Exams]的主要内容,如果未能解决你的问题,请参考以下文章

timus1745题解

timus 1033 Labyrinth(BFS)

Timus 1146. Maximum Sum

1923. Scary Politics (timus) (dfs) search

timus 1109 Conference(二分图匹配)

timus 1180. Stone Game 解题报告