작성일 :

문제 링크https://soo-bak.github.io/algorithm/boj/bridgeComb-50/#문제-링크

1010번 - 다리 놓기

설명https://soo-bak.github.io/algorithm/boj/bridgeComb-50/#설명

이 문제는 서쪽 N개, 동쪽 M개의 사이트가 주어졌을 때,
서쪽 사이트와 동쪽 사이트를 1대1로 연결하는 다리를 만들 수 있는 경우의 수를 구하는 문제입니다.

단, 다리는 서로 겹치지 않아야 하고 항상 왼쪽에서 오른쪽으로만 연결됩니다.

이는 수학적으로 조합(combination) 문제로, 다음 공식을 통해 해결할 수 있습니다:

C(M,N)=M!N!(MN)!C(M, N) = \frac{M!}{N!(M-N)!}

접근법https://soo-bak.github.io/algorithm/boj/bridgeComb-50/#접근법

  • 문제는 중복 없는 조합의 수를 계산하는 방식으로, 직접 팩토리얼을 모두 계산하면 오버플로우가 발생할 수 있습니다.
  • 따라서, 곱셈과 나눗셈을 반복적으로 적용하여 C(M, N)을 계산합니다.
  • M개의 수 중 N개를 선택하는 것이므로, M에서 N개를 곱하면서 동시에 N!로 나눠줍니다.

Codehttps://soo-bak.github.io/algorithm/boj/bridgeComb-50/#code

[ C# ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;

namespace Solution {
  class Program {
    static void Main(string[] args) {
      int t = int.Parse(Console.ReadLine()!);
      while (t-- > 0) {
        var input = Console.ReadLine()!.Split();
        int n = int.Parse(input[0]);
        int m = int.Parse(input[1]);

        long res = 1;
        int r = 1;
        for (int i = m; i > m - n; i--) {
          res *= i;
          res /= r++;
        }
        Console.WriteLine(res);
      }
    }
  }
}



[ C++ ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main() {
  ios::sync_with_stdio(false);

  int t; cin >> t;
  while (t--) {
    int cntBrg, cntRSite; cin >> cntBrg >> cntRSite;

    ll ans = 1, r = 1;
    for (int i = cntRSite; i > cntRSite - cntBrg; i--) {
      ans *= i;
      ans /= r++;
    }

    cout << ans << "\n";
  }

  return 0;
}