[SWEA 6898] 규영이와 인영이의 카드게임
업데이트:
문제
- SWEA 0898번
- 문제의 저작권은 SW Expert Academy에 있습니다.
접근방식
이 문제는 순열과 관련된 문제이다.
문제에서 1부터 18까지의 카드를 각자 9개씩 나누어 가진다고 하고 규영이는 9개의 고정된 입력값이 들어온다. 따라서 전체 카드에서 규영이가 가진 만큼을 뺀 나머지 카드를 인영이가 가지게 된다.
이렇게 인영이가 가질 수 있는 배열만 모아논 myCard배열을 만든 후, 각 카드들이 순서가 어떻게 되느냐에 따라서 규영이와의 게임의 결과가 달라지게 된다. 따라서 9개의 서로 다른 카드를 순서있게 정하는 방법인 순열을 적용하도록 한다.
함수 per()에서 카드를 한장씩 뽑아가면서 순열을 만드는데 만약 카드를 다 뽑은 경우에는 규영이와 i=0에 위치한 카드부터 끝까지 비교해가면서 각자의 이긴 점수를 저장한 후에 누가 이기고 졌는지를 체크한다. 모든 재귀를 반복하게 되면 나올 수 있는 모든 경우의 수를 다 따져본 것이므로 이때 구한 규영이가 이기는 경우와 질 경우를 출력해준다.
코드
import java.util.Arrays;
import java.util.Scanner;
public class Swea_6808 {
static final int SIZE = 9; // 각자 카드 수
static int[] allCard; // 전체 카드 1~18
static int[] partner; // 규영이 고정 카드
static int[] myCard; // 전체-규영 카드(인영카드)
static int[] numbers; //뽑은 카드
static boolean[] isSelected;
static int win, lose;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int tc = 0; tc < T; tc++) {
partner = new int[SIZE];
allCard = new int[SIZE * 2 + 1];
numbers = new int[SIZE];
isSelected = new boolean[SIZE];
win = 0;
lose = 0;
// 규영 고정
for (int i = 0; i < 9; i++) {
partner[i] = sc.nextInt();
// 전체 카드에 해당 카드 인덱스를 이미 사용됐다고 표시
allCard[partner[i]] = -1;
}
myCard = new int[SIZE];
// 사용되지 않은 카드 배열 만들기
for (int i = 0; i < SIZE; i++) {
for (int j = 1; j < allCard.length; j++) {
if (allCard[j] != -1) { //사용안했다면
myCard[i] = j;
allCard[j] = -1;
break;
}
}
}
// 9!만들기
per(0);
System.out.println("#"+(tc+1)+" "+win+" "+lose);
}
}
//9개의 카드를 순서있게 뽑기(순열)
public static void per(int cnt) { // cnt: 현재까지 뽑힌 개수
// 다 뽑았으면
if (cnt == SIZE) {
// 값 비교
int my_sum = 0; //인영이 점수
int part_sum = 0; //규영이 점수
// 9번 라운드
for (int i = 0; i < SIZE; i++) {
if (numbers[i] > partner[i]) //인영이가 이겼다면
my_sum += numbers[i] + partner[i];
else if (numbers[i] < partner[i])//규영이 이겼다면
part_sum += numbers[i] + partner[i];
else //비겼다면
continue;
}
if(part_sum > my_sum) win++; //규영이가 이김
else if(part_sum < my_sum) lose++; //규영이가 짐
return; // 재귀 탈출
}
for (int i = 0; i < SIZE; i++) {
// 중복 확인
if (isSelected[i])
continue;
numbers[cnt] = myCard[i]; // 해당숫자 사용
isSelected[i] = true;
per(cnt + 1); // 다음 자리 순열 뽑기
isSelected[i] = false;
}
}
}