반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
05-19 04:57
관리 메뉴

ImJay

[SWEA/Java] 6808. 규영이와 인영이의 카드게임 본문

SW Expert Academy/D3

[SWEA/Java] 6808. 규영이와 인영이의 카드게임

ImJay 2024. 4. 18. 01:00
반응형

[SWEA/Java] 6808. 규영이와 인영이의 카드게임

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


문제 해석

규영이와 인영이는 각각 9장의 카드를 가지고 게임을 한다. 이 게임에서는 총 18장의 카드가 사용되며, 각 카드에는 1부터 18까지의 숫자가 적혀 있다. 규영이의 카드는 입력으로 주어지며, 인영이는 남은 카드를 가진다. 이 게임에서 각 턴에 두 사람은 자신의 카드 중 하나를 내고, 더 높은 숫자의 카드를 낸 사람이 점수를 얻는다. 이 점수는 두 카드의 숫자를 합한 값이다. 모든 카드가 사용될 때까지 게임을 계속하며, 게임이 끝난 후 더 많은 점수를 획득한 사람이 승리한다. 이 문제에서는 규영이와 인영이가 획득할 수 있는 모든 승리 조합의 수를 구해야 한다.

풀이 과정

제출된 Java 코드는 주어진 규영이의 카드를 바탕으로 인영이의 카드를 구성하고, 모든 가능한 순열을 생성하여 각 순열에 대해 점수를 계산하는 방식으로 문제를 해결한다. 이를 위해 백트래킹과 비트마스킹을 사용해 효율적인 순열 생성을 진행한다.

 

  • 데이터 입력: 입력 데이터로부터 테스트 케이스 수와 규영이의 카드를 받는다.
  • 카드 배열 구성: 규영이의 카드를 제외한 나머지 카드를 인영이의 카드 배열로 구성한다.
  • 순열 생성 및 점수 계산 (permutation 메소드): 카드 순열을 생성하면서 각 카드의 대결에서 점수를 계산한다. 모든 카드가 사용된 후 최종 점수를 비교하여 승리 횟수를 갱신한다.

코드

package edu.ssafy.im.SWEA.D3.No6808;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Solution {
	private final static int SIZE = 9; // 카드 수
	private int[] arr; // 규영이의 카드 배열
	private int[] card; // 인영이의 카드 배열
	private int[] sel; // 현재 순열의 카드
	private int sw; // 규영이의 승리 횟수
	private int aw; // 인영이의 승리 횟수

	public static void main(String[] args) throws NumberFormatException, IOException {
		new Solution().io();
	}

	private void io() throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringBuilder sb = new StringBuilder();
		int testCase = Integer.parseInt(br.readLine());

		for (int t = 1; t <= testCase; t++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			arr = new int[SIZE]; // 규영이의 카드 초기화
			for (int i = 0; i < SIZE; i++) {
				arr[i] = Integer.parseInt(st.nextToken());
			}
			card = new int[SIZE]; // 인영이의 카드 배열
			int idx = 0;
			for (int i = 1; i <= SIZE * 2; i++) {
				boolean flag = true;
				for (int j = 0; j < SIZE; j++) {
					if (arr[j] == i) {
						flag = false;
						break;
					}
				}
				if(flag) {
					card[idx] = i;
					idx++;
				}
			}
			sw = 0; aw = 0;
			sol();
			sb.append("#").append(t).append(" ").append(aw).append(" ").append(sw).append("\n");
		}
		bw.write(sb.toString());
		bw.flush();
		bw.close();
	}

	private void sol() {
		sel = new int[SIZE]; // 순열을 위한 선택 배열
		permutation(0, 0);
	}

	private void permutation(int k, int v) {
		if (k == SIZE) {
			int ss = 0, as = 0; // 규영이와 인영이의 점수
			for (int i = 0; i < SIZE; i++) {
				if(sel[i] > arr[i]) {
					ss += sel[i] + arr[i]; // 규영이 승리
				} else {
					as += sel[i] + arr[i]; // 인영이 승리
				}
			}
			if (ss > as) {
				sw += 1; // 규영이 승리 횟수 추가
			} else if (as > ss) {
				aw += 1; // 인영이 승리 횟수 추가
			}
			return;
		}

		for (int i = 0; i < SIZE; i++) {
			if ((v & (1 << i)) == 0) {
				sel[k] = card[i]; // 카드 선택
				permutation(k + 1, v | 1 << i); // 다음 카드 선택
			}
		}
	}
}

시간 복잡도 분석

이 알고리즘의 시간 복잡도는 순열을 생성하는 데 필요한 비용으로, 최악의 경우 9! (362880) 회의 순열을 생성해야 한다. 각 순열에 대한 처리는 이므로, 전체 시간 복잡도는 이다.

느낀점

이 문제를 통해 순열을 사용하여 다양한 경우의 수를 고려하고, 조건에 따라 결과를 계산하는 방식을 연습할 수 있었다. 이러한 접근 방식은 조합적 문제 해결에 널리 사용되며, 다양한 분야에 적용될 수 있다.

반응형
Comments