Soluție HackerRank pentru Alien Flowers, subdomeniul Combinatorics, în C++14. Include cerința formatată, exemple, explicația pașilor și cod sursă.

  • Problemă: Alien Flowers
  • Domeniu: Combinatorics
  • Limbaj: C++14

Challenge: Alien Flowers

Subdomeniu: Combinatorics (combinatorics)

Scor cont: 60.0 / 60

Submission status: Accepted

Submission score: 1.0

Submission ID: 464755270

Limbaj: cpp14

Link challenge: https://www.hackerrank.com/challenges/alien-flowers/problem

Cerință

Meera bought a house on Mars, and plans to decorate it with chains of alien flowers. Each flower is either red (R) or blue (B), and Meera knows how many occurrences of `RR`, `RB`, `BB`, and `BR` she wants to see in a chain.

The diagram below shows a flower chain of length 10:

ornament.jpg

In this example, `RR` occurs 2 times (at positions 0 and 4), `RB` occurs 3 times (at positions 1, 5, and 7), `BB` occurs 1 time (at position 2), and `BR` occurs 3 times (at positions 3, 6, and 8).

Meera wants your help determining how many different chains with *positive length* can be made. Given A, B, C, and D, find the number of different chains having occurrences of `RR`, `RB`, `BB` and `BR` equal to inputs A, B, C, and D, respectively. As the answer can be very large, your printed output should be answer % (10^9+7).

Input Format

One line of space-separated, non-negative integers: A (occurrences of `RR`), B (occurrences of `RB`), C (occurrences of `BB`), and D (occurrences of `BR`), respectively.

Output Format

Find the number of chains having A, B, C, and D occurrences of `RR`, `RB`, `BB`, and `BR`, respectively, and print the answer % (10^9+7).

Constraints

* For 20% Points: 0 ≤ A,B,C,D ≤ 4

* For 50% Points: 0 ≤ A,B,C,D ≤ 10^2

* For 100% Points: 0 ≤ A,B,C,D ≤ 10^5

Cod sursă

#include <bits/stdc++.h>
using namespace std;

static const long long MOD = 1000000007LL;

long long mod_pow(long long a, long long e) {
    long long r = 1 % MOD;
    a %= MOD;
    while (e > 0) {
        if (e & 1) r = (r * a) % MOD;
        a = (a * a) % MOD;
        e >>= 1;
    }
    return r;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    long long rr, rb, bb, br;
    cin >> rr >> rb >> bb >> br;

    if (llabs(rb - br) > 1) {
        cout << 0 << '\n';
        return 0;
    }

    long long maxK = max(rb, br);
    if (maxK >= MOD) {
        // Not expected under problem constraints.
        cout << 0 << '\n';
        return 0;
    }

    vector<long long> inv((size_t)maxK + 1, 1);
    for (long long i = 2; i <= maxK; ++i) {
        inv[(size_t)i] = MOD - (MOD / i) * inv[(size_t)(MOD % i)] % MOD;
    }

    auto comb = [&](long long n, long long k) -> long long {
        if (k < 0 || k > n) return 0;
        k = min(k, n - k);
        long long res = 1;
        for (long long i = 1; i <= k; ++i) {
            long long num = (n - k + i) % MOD;
            res = (res * num) % MOD;
            res = (res * inv[(size_t)i]) % MOD;
        }
        return res;
    };

    auto ways = [&](long long internal, long long runs) -> long long {
        if (runs == 0) return internal == 0 ? 1LL : 0LL;
        return comb(internal + runs - 1, runs - 1);
    };

    long long ans = 0;

    if (rb == br) {
        long long t = rb;
        // Start and end with R: R-runs=t+1, B-runs=t
        ans = (ans + ways(rr, t + 1) * ways(bb, t)) % MOD;
        // Start and end with B: R-runs=t, B-runs=t+1
        ans = (ans + ways(rr, t) * ways(bb, t + 1)) % MOD;
    } else if (rb == br + 1) {
        long long t = rb;
        // Start with R, end with B: R-runs=t, B-runs=t
        ans = (ans + ways(rr, t) * ways(bb, t)) % MOD;
    } else {
        long long t = br;
        // Start with B, end with R: R-runs=t, B-runs=t
        ans = (ans + ways(rr, t) * ways(bb, t)) % MOD;
    }

    cout << ans % MOD << '\n';
    return 0;
}
HackerRank Combinatorics – Alien Flowers