되는대로 살자

[C언어 기출문제&풀이] 쌓아 올리기(Stack 'em Up) 본문

2009~2014/C/C++

[C언어 기출문제&풀이] 쌓아 올리기(Stack 'em Up)

malu 2011. 5. 15. 23:33

빅 시티(Big city)에는 카지노가 여러 개 있다. 그 중 한 카지노에 있는 딜러가 속임수를 쓴다. 그녀는 몇 가지 카드 섞는 법을 완벽하게 익혔는데, 그 카드 섞는 법을 사용하면 언제든지 카드를 마음대로 재배치할 수 있다. 간단한 예로 "밑장"섞기를 들 수 있는데, 맨 아래 있는 카드를 꺼내서 맨 위로 올려놓는 방법이다. 그 딜러는 이런 다양한 섞기 방법을 조합해서 원하는 순서대로 카드를 쌓아 올릴 수 있다.

카지노의 보안 관리자가 그 딜러를 감시하기 위해 당신을 고용했다. 딜러가 섞은 모든 카드 순서가 주어지며 사용된 섞기 방법도 제공된다. 이런 정보가 주어졌을 때 몇 번의 섞기 작업이 진행된 후의 카드 순서를 예측해야 한다.

카드 한 벌은 52개의 카드로 구성되며 네 개의 무늬마다 13장의 카드가 있다. 카드의 값(숫자)은 2,3,4,5,6,7,8,9,10,Jack,Queen,King,Ace 중 하나다. 그리고 무늬는 Clubs,Diamonds,Heaqrts,Spades 가운데 하나다. 각 카드는 <값> of <무늬>와 같은 식으로 값과 무늬를 써서 유일하게 식별할 수 있다. 예를 들면 "9 of Hearts", "King of Spades"같은 식으로 표현할 수 있다. 관례에 따라 새 카드는 우선 무늬를 기준으로 알파벳 순으로, 그리고 위에 나와있는 값 순서대로 정렬된다.

입력: 입력은 테스트 케이스의 개수를 나타내는 숫자 하나만 들어있는 줄로 시작되며 그 다음 줄은 빈 줄이다. 또한 두 개의 연속된 테스트 케이스 사이에도 빈 줄이 하나씩 들어간다.
각 케이스는 딜러가 알고 있는 섞기 방법의 개수인 100 이하의 정수 n으로 시작된다. 그 다음 줄에는 52개의 정수가n세트 나오는데 각 세트에는 1에서 52까지의 모든 정수가 들어있다. 52개의 정수로 구성된 각 세트 내에서 j위치에 i가 있다는 것은 패에서 i번째 카드를 j번째 위치로 이동시킨다는 것을 의미한다.
그 뒤에는 각각 1 이상 n이하의 정수 k가 들어있는 행이 여러 개 뒤따른다. 입력도니 정수k는 딜러가 k번째 섞기 방법을 썼다는 것을 나타낸다.

출력:각 테스트 케이스에 대해 딜러가 위에 기술되어 있는 대로 정렬된 새로운 패를 가지고 시작한다고 가정하고 섞기가 모두 끝난 후에 새로운 순서에 따라서 카드의 이름을 출력한다. 두 개의 서로 다른 케이스에 대한 출력 결과는 빈 줄로 구분한다.

풀이: 문제 조건대로 처리한다. 주석을 보면 이해할 수 있을 것이다.

소스코드 #include <stdio.h>

#define NUM_CARDS 52
#define MAX_SHUFFLES 100

void main(void)
{
 int shuffle[MAX_SHUFFLES +1][NUM_CARDS + 1];
 int deck[NUM_CARDS +1], old_deck[NUM_CARDS + 1];
 char line[100];
 int num_cases, num_shuffles;
 int t,i,j,k,suit,value;

 scanf("%d",&num_cases);
 for(t=0;t<num_cases;t++)
 {
  scanf("%d",&num_shuffles);
  for(i=1;i<=num_shuffles;i++)
   for(j=1;j<=NUM_CARDS;j++)
    scanf("%d",&shuffle[i][j]);
   for(i=1;i<=NUM_CARDS;i++)
    deck[i]=i;
   
   gets(line);
   while(gets(line)&&*line)
   {
    sscanf(line,"%d",&k);
    for(i=1;i<=NUM_CARDS;i++)
     old_deck[i]=deck[i];
    for(i=1;i<=NUM_CARDS;i++)
     deck[i]=old_deck[shuffle[k][i]];
   }
   
   if(t>0)
    putchar('\n');

   for(i=1;i<=52;i++)
   {
    value=(deck[i] -1)%13;
    suit = (deck[i] -1) / 13;
    switch(value)
    {
    case 9:printf("Jack"); break;
    case 10:printf("Queen"); break;
    case 11:printf("King"); break;
    case 12:printf("Ace"); break;
    default:printf("%d", value+2); break;
    }
    printf(" of ");
    switch(suit)
    {
    case 0:puts("clubs"); break;
    case 1:puts("Diamonds"); break;
    case 2:puts("Hearts"); break;
    case 3:puts("Spades"); break;
    }
   }
 }
}