LoginSignup
1
1

More than 5 years have passed since last update.

40 C 20 を解く

Posted at

プロジェクトオイラー15らしいです。
階乗すぐオーバーフローしてしまうので、
先に約分をするというのがミソです。
アルゴリズム力をちょっとづつのばしていきたいところです。
命名とかやっつけです

#include <iostream>
#include <vector>

//a >= b
long long int gcd(long long int a, long long int b)
{
    long long int mod = a % b;
    if(mod == 0)
        return b;
    return gcd(b, mod);
}

void fact(std::vector<long long int> &array)
{
    for(long long int i = 0 ; i < array.size() ; ++i)
    {
        array[i] = (long long int)array.size() - i;
    }
}

void reduce(std::vector<long long int> &child, std::vector<long long int> &mother)
{
    for(long long int &c : child)
    {
        for(long long int &m : mother)
        {
            long long int n = (c > m)? gcd(c, m) : gcd(m, c);
            c /= n;
            m /= n;
        }
    }
}

long long int comb(long long int a, long long int b)
{
    std::vector<long long int> child(a);
    std::vector<long long int> mother1(b);
    std::vector<long long int> mother2(a - b);

    fact(child);
    fact(mother1);
    fact(mother2);

    std::vector<long long int> mother;
    mother.insert(mother.end(), mother1.begin(), mother1.end());
    mother.insert(mother.end(), mother2.begin(), mother2.end());

    reduce(child, mother);

    long long int c = 1;
    long long int m = 1;
    std::for_each(child.begin(), child.end(), [&c](long long int n){ c *= n; });
    std::for_each(mother.begin(), mother.end(), [&m](long long int n){ m *= n; });

    return c / m;
}
int main(int argc, const char * argv[])
{
    std::cout << comb(40, 20);
    return 0;
}
1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1