码迷,mamicode.com
首页 > 其他好文 > 详细

Timus[1091. Tmutarakan Exams]

时间:2018-11-17 16:04:57      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:一个   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;
}
Solution.

 

Timus[1091. Tmutarakan Exams]

标签:一个   col   rod   cout   include   输入   return   分享   blank   

原文地址:https://www.cnblogs.com/knull/p/9973888.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!