본문 바로가기
알고리즘

백준 g3 16986 인싸들의 가위바위보 c++

by kyj0032 2024. 1. 21.

https://www.acmicpc.net/problem/16986

 

16986번: 인싸들의 가위바위보

두 사람이 같은 손동작을 내어 무승부가 발생할 경우 경기 진행 순서상 뒤인 사람이 이긴 것으로 간주함에 다시 한 번 유의한다. 구체적으로, 경기 진행 순서는 지우, 경희, 민호 순으로 고정되

www.acmicpc.net

 

헷갈릴 수 있는 요소

 

문제가 헷갈린다는 평이 많다. 그러니 문제를 읽고 나서 풀기 전에 꼭 예제 밑에 있는 노트를 읽어보자.

  • 주어지는 경희, 민호의 손동작 순서는 라운드별이 아닌, 자신이 경기를 하나 참여할 때마다 하나씩 쓰는 것.
    • ex. 지우vs경희, 경희vs 민우 경기를 차례대로 진행한다고 가정했을 때, 2번째 경기에서 민우는 자신의 두번째 손동작을 내는 것이 아니라, 첫 번째 손동작을 낸다. 그 이후에 경기에 참여하게 되면, 몇 번째 경기이냐는 상관없이 두번째 손동작을 낸다.
  • 두 사람이 비겼을 경우에는 경기 진행 순서상 뒤인 사람이 승리한다.
    • 여기서 경기 진행 순서란 지우 - 경희 - 민호이다. 따라서 만약 경희 vs. 지우 경기가 비겼다면 경희의 승리이다.
    • 나는 경기 진행 순서를 지우-경희-민호가 아니라, A vs B 일 때 B라고 잘못 이해해서 시간을 많이 날렸다. 예시에도 나와있는 내용이니 예시가 주어졌으면 예시를 꼼꼼히 보자..

문제 설명

  • input
    • 손동작 N개, 승리 횟수 K, 손동작 N*N들의 상성 (Ai,j가 2면 i승, 1이면 비김, 0이면 패)
    • 경희, 민호가 낼 손동작 20개
  • output
    • 지우가 매 경기마다 손동작을 다르게 낼 때, 승리할 수 있으면 1 그렇지 않으면 0 출력

수도 코드

dfs(a vs b) // a vs b 경기 진행
	if ans == 1 // 이미 우승 가능하다고 판별났으므로 더 할 필요 X
    	return
    if 우승횟수[지우] == K
    	ans = 1
        return
    else if 우승횟수[경희] == K || 우승횟수[민호] == K
    	return
    
    for(i: 1~N 지우가 사용할 손동작)
    	if used[i]
        	continue
        a의 손동작 vs b의 손동작
        
        used[i] = 1
        우승횟수[winner]++
        dfs(winner, 나머지)
        
        used[i] = 0
        우승횟수[winner]--

 

 

전체 코드

/*boj g3 16986 인싸들의 가위바위보*/
#include <iostream>
#define MAXN 10
using namespace std;

int N, K;
int wins[3]; // 0 지우, 1 경희, 2 민우
int compatibility[MAXN][MAXN];
int used[MAXN];
int cur1 = 0;
int cur2 = 0;

int player1[22]; // 1이면 경희, 2면 민우, 0은 비어있음
int player2[22];

int ans = 0;

void input() {
    cin >> N >> K;
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> compatibility[i][j];
        }
    }

    for (int j = 0; j < 20; j++) {
        cin >> player1[j];
    }

    for (int j = 0; j < 20; j++) {
        cin >> player2[j];
    }
}

int gesture(int a, int i) {
    int res = -1;
    if (a == 0) { // 지우의 gesture
        res = i;
    } else if (a == 1) { // 경희의 gesture
        res = player1[cur1];
        cur1++;
    } else if (a == 2) { // 민호의 gesture
        res = player2[cur2];
        cur2++;
    }

    return res;
}

int getOther(int a, int b) {
    int check[3] = {0, 0, 0};
    check[a] = 1;
    check[b] = 1;

    for (int i = 0; i < 3; i++) {
        if (check[i] == 0) return i;
    }
}

void dfs(int a, int b) {
    if (ans == 1) return; // 이미 가능으로 판별남

    if (wins[0] == K) {
        ans = 1;
        return;
    } else if (wins[1] == K || wins[2] == K) {
        return;
    }

    if (cur1 >= 20 || cur2 >= 20) return;

    if (a == 0 || b == 0) { // 지우 경기
        for (int i = 1; i <= N; i++) {
            if (used[i]) continue;

            int x = gesture(a, i);
            int y = gesture(b, i);

            int winner;
            int fightRes = compatibility[x][y];

            if (fightRes == 2)
                winner = a;
            else if (fightRes == 1)
                winner = a > b ? a : b;
            else
                winner = b;

            used[i] = 1;
            wins[winner]++;
            int other = getOther(a, b);

            dfs(winner, other);
            wins[winner]--;
            used[i] = 0;

            if (a == 1 || b == 1)
                cur1--;
            else if (a == 2 || b == 2)
                cur2--;

            if (ans) return;
        }
    } else { // 경희 민호 경기
        int x = gesture(a, -1);
        int y = gesture(b, -1);

        int winner;
        int fightRes = compatibility[x][y];

        if (fightRes == 2)
            winner = a;
        else if (fightRes == 1)
            winner = a > b ? a : b;
        else
            winner = b;
        wins[winner]++;

        dfs(winner, 0); // 다음은 승자 vs 지우
        wins[winner]--;
        cur1--;
        cur2--;
    }
}

int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
    input();

    dfs(0, 1);

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

'알고리즘' 카테고리의 다른 글

백준 g2 17825 주사위 윷놀이 c++  (0) 2024.01.22
백준 g2 17822 원판 돌리기 c++  (0) 2024.01.22
백준 g1 17143 낚시왕 c++  (0) 2024.01.20
백준 g1 13460 구슬 탈출 2 c++  (0) 2024.01.19
백준 g2 16985 Maaaaaaaaaze c++  (0) 2024.01.18