Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 주사위 던지기 게임에서 두 플레이어의 승리·무승부 경우의 수 계산하기

두 개의 숫자 a와 b가 주어져 있다고 가정해 봅시다. 아말(Amal)과 비말(Bimal)이 주사위 게임을 하고 있습니다. 두 사람은 먼저 각자 1부터 6 사이의 정수를 하나씩 적어둔 뒤 주사위를 던집니다. 적어둔 숫자가 주사위에 나온 눈금에 더 가까운 플레이어가 해당 라운드에서 승리하며, 두 사람과 주사위 눈금의 차이가 같다면 무승부가 됩니다. 아말이 a를, 비말이 b를 적었다고 할 때, 아말이 이기는 경우의 수, 무승부가 되는 경우의 수, 비말이 이기는 경우의 수를 각각 구해야 합니다.

예를 들어 입력이 a = 2, b = 4라고 한다면 출력은 [2, 1, 3]이 됩니다. 즉, 아말은 2가지 경우에서 승리할 수 있고, 주사위가 3이 나오면 무승부가 되며, 나머지 3가지 경우는 비말이 승리합니다.

문제 해결 접근 방법

이 문제는 주사위 눈금이 1부터 6까지 총 6가지뿐이라는 점을 활용하면 반복문 없이 수학적 계산만으로 해결할 수 있습니다. 풀이 과정은 다음과 같습니다.

  • 아말의 승리 횟수 s1, 무승부 횟수 s2, 비말의 승리 횟수 s3를 0으로 초기화합니다.
  • (a + b)가 짝수라면 두 숫자의 정중앙 값이 정수가 되므로, 그 눈금에서는 반드시 무승부가 발생합니다. 따라서 s2 := 1로 설정합니다.
  • a == b라면 어떤 눈금이 나오더라도 두 사람의 거리 차이가 항상 같으므로 모든 경우가 무승부입니다. 따라서 s2 := 6으로 설정합니다.
  • a > b인 경우 아말이 더 작은 수를 적어둔 것이므로, 주사위가 두 숫자의 중간값보다 작게 나왔을 때 아말이 승리합니다. 따라서 s1 := 6 − ((a + b) / 2)로 계산합니다.
  • a < b인 경우에는 s1 := (a + b − s2 − 1) / 2로 계산합니다.
  • 마지막으로 전체 6가지 경우에서 나머지를 빼서 s3 := 6 − s1 − s2를 구한 뒤, 세 값을 출력합니다.

C++ 구현 예제

위 로직을 실제 코드로 구현하면 다음과 같습니다.

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

void solve(int a, int b) {
    int s1 = 0, s2 = 0, s3 = 0;
    if ((a + b) % 2 == 0)
        s2 = 1;
    if (a == b)
        s2 = 6;
    else if (a > b)
        s1 = 6 - ((a + b) / 2);
    else
        s1 = (a + b - s2 - 1) / 2;
    s3 = 6 - s1 - s2;
    cout << s1 << ", " << s2 << ", " << s3 << endl;
}
int main() {
    int a = 2;
    int b = 4;
    solve(a, b);
}

입력

2, 4

출력

2, 1, 3

동작 원리 살펴보기

a = 2, b = 4인 경우 주사위 눈금별 결과를 직접 확인해 보면 다음과 같습니다.

  • 주사위가 1 또는 2가 나오면 아말이 적은 숫자에 더 가까우므로 아말이 승리합니다 (2가지).
  • 주사위가 3이 나오면 두 사람 모두 거리가 1로 같으므로 무승부입니다 (1가지).
  • 주사위가 4, 5, 6이 나오면 비말이 적은 숫자에 더 가까우므로 비말이 승리합니다 (3가지).

이처럼 조건 분기와 간단한 산술 연산만으로 O(1) 시간 복잡도 안에 세 가지 경우의 수를 모두 구할 수 있습니다.