https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWgv9va6HnkDFAW0 

 

SW Expert Academy

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

swexpertacademy.com

 

[문제]

 

규영이와 인영이는 1에서 18까지의 수가 적힌 18장의 카드로 게임을 하고 있다.

한 번의 게임에 둘은 카드를 잘 섞어 9장씩 카드를 나눈다. 그리고 아홉 라운드에 걸쳐 게임을 진행한다.

한 라운드에는 한 장씩 카드를 낸 다음 두 사람이 낸 카드에 적힌 수를 비교해서 점수를 계산한다.

높은 수가 적힌 카드를 낸 사람은 두 카드에 적힌 수의 합만큼 점수를 얻고,

낮은 수가 적힌 카드를 낸 사람은 아무런 점수도 얻을 수 없다.

이렇게 아홉 라운드를 끝내고 총점을 따졌을 때, 총점이 더 높은 사람이 이 게임의 승자가 된다.

두 사람의 총점이 같으면 무승부이다.

이번 게임에 규영이가 받은 9장의 카드에 적힌 수가 주어진다.

규영이가 내는 카드의 순서를 고정하면, 인영이가 어떻게 카드를 내는지에 따른 9!가지 순서에 따라

규영이의 승패가 정해질 것이다.

이 때, 규영이가 이기는 경우와 지는 경우가 총 몇 가지 인지 구하는 프로그램을 작성하라.


[입력]

첫 번째 줄에 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스의 첫 번째 줄에는 아홉 개의 정수가 공백으로 구분되어 주어진다.

각 정수는 1이상 18이하이며, 같은 정수는 없다.

규영이는 정수가 주어지는 순서대로 카드를 낸다고 생각하면 된다.


[출력]

각 테스트 케이스마다 ‘#x’(x는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고 한 칸을 띄운 후,

인영이가 카드를 내는 9! 가지의 경우에 대해 규영이가 게임을 이기는 경우의 수와 게임을 지는 경우의 수를

공백 하나로 구분하여 출력한다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution {
	static int T = 9;
	static int kscore=0;
	static int iscore=0;
	static int win;
	static int lose;

	private static void makePermutation(int[] Karr, int[] Iarr, int toSelect, int[] selected, boolean[] visited) {
		if (toSelect == T) {
			kscore = 0;
			iscore = 0;
			for (int i = 0; i < T; i++) {
				if (Karr[i] > Iarr[selected[i]]) {
					kscore += Karr[i] + Iarr[selected[i]];
				} else
					iscore += Karr[i] + Iarr[selected[i]];
			}
			if (kscore > iscore)
				win++;
			else
				lose++;
			return;
		}
		for (int i = 0; i < T; i++) {
			if (!visited[i]) {
				visited[i] = true;
				selected[toSelect] = i;
				makePermutation(Karr, Iarr, toSelect + 1, selected, visited);
				visited[i] = false;
			}
		}
	}

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		StringBuilder sb = new StringBuilder();
		int TC = Integer.parseInt(br.readLine());
		for (int t = 1; t <= TC; t++) {
			sb.append("#" + t + " ");
			String str = br.readLine();
			st = new StringTokenizer(str, " ");
			int[] kcard = new int[T];
			for (int i = 0; i < T; i++) {
				kcard[i] = Integer.parseInt(st.nextToken());
			}
			int[] Icard = new int[T];
			for (int k = 0, i = 1; i <= 2 * T; i++) {
				int flag = 0;
				for (int j = 0; j < T; j++) {
					if (i == kcard[j])
						flag = 1;
				}
				if (flag == 0) {
					Icard[k] = i;
					k++;
				}
			}
			win = 0;
			lose = 0;
			makePermutation(kcard, Icard, 0, new int[T], new boolean[T]);
			sb.append(win + " " + lose + "\n");
		}
		System.out.println(sb);
	}
}

 

인영이와 규영이의 카드는 겹치지 않으므로 이중for문을 통해 규영이의 카드에 따른 인영이의 카드 배열을 저장해주었습니다. 

 

int[] Icard = new int[T];
for (int k = 0, i = 1; i <= 2 * T; i++) {
int flag = 0;
for (int j = 0; j < T; j++) {
if (i == kcard[j])
flag = 1;
}
if (flag == 0) {
Icard[k] = i;
k++;
}
}

 

 

인영이의 카드 내는 순서의 순열을 구하는 makePermutation 재귀 함수를 작성해 풀이해주었습니다.

순열이 정해질 때마다 규영이와 인영이의 점수를 초기화한 뒤 서로의 점수를 구해줍니다.

점수계산 후 규영이의 점수가 더 높다면 win++ 아니라면 lose ++을 해주었습니다.

if (toSelect == T) {

kscore = 0;
iscore = 0;
for (int i = 0; i < T; i++) {
if (Karr[i] > Iarr[selected[i]]) {
kscore += Karr[i] + Iarr[selected[i]];
} else
iscore += Karr[i] + Iarr[selected[i]];
}
if (kscore > iscore)
win++;
else
lose++;
return;
}

 

+ Recent posts