sicily 1018. A Card Trick

1018. A Card Trick

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

The following card trick is performed by a Magician and her Assistant. The Assistant asks a member of the audience to choose 5 cards from a standard deck of 52 cards (A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K of C[lubs], D[iamonds], H[earts] and S[pades]). The Assistant returns one of the cards to the audience member and then hands the remaining cards to the Magician, one at a time. After suitable mumbo-jumbo, the Magician identifies the (fifth) card held by the audience member.   

The Magician determines the card as follows:   

The order of the cards in the deck is determined first by the value and for cards of the same value by the suit (both in the order given above). So the total order of cards is: AC, AD, AH, AS, 2D, … , KH, KS   

  1. Remember the suit and value of the first card.  
  2. Among the remaining three cards find the position of the smallest card (in the above order). Add this position (1, 2, or 3) to the value of the first card.  
  3. If the larger two of the last three cards are not in order, add 3 to the result of step 2.  
  4. The missing card has the same suit as the first card and value that computed in step 3 wrapping around if necessary.    

For example:   

QH, 10D, 10C, 4D   

Smallest of the last 3 cards is 4D in place 3. 10D and 10C are out of order so add 3 + 3 to Q. Wrapping around the missing card is 5H.  

This problem is to write a program to perform the function of the Assistant.

Input

The first line of the input file named j.in consists of a positive integer n, which is the number of datasets that follow. Each of the n following lines contain one data set. The dataset is a sequence of 5 cards separated by a space. Each card is given by a one or two character value and a one character suit as described in the first paragraph.

Output

For each dataset, the output on separate lines is an ordering of the 5 input cards as shown in the sample output. The first card in the sequence is the card to be returned to the audience member. The remaining cards are those given to the Magician (in the order given to the Magician). There may be more than one solution to some problems (but that is not to say there *will* be). In cases such as these, any of the correct solutions will be accepted by the judges. For instance 10D 4D QH 10C 5H is also a solution to the first problem below.

Sample Input

2						4D 5H 10C 10D QH			7H 5C KS 6C 8D 

Sample Output

Problem 1: 5H QH 10D 10C 4DProblem 2: 6C 5C 7H 8D KS

题目分析

将给定的牌排序输出
助手找出两张同样花色的牌,看点数,
例如是2和7,由于7-2=5<=6,让7放前面。
如果是2和9,9-2=7>6,那么让2放前面。
使得前面的牌的点数a和后面的牌的点数b满足(a-b+13)%13<=6
剩下的三张牌中,找出最小的那张,A最小,K最大
假设之前的(a-b+13)%13=c(0<c<=6)
在剩下的三张牌中,如果 c<=3,让最小的牌放在第 c+1 个位置,
否则放在第 c-2 个位置
剩下的两张牌,如果 c > 3, 那么使前面那张牌比后面大,
否则使前面那张牌比后面小。


#include <iostream>

struct Card {
  int digit;
  char suit;
};
Card sorted[5];
Card unsorted[5];
void assign(Card &a, Card &b) {
  a.suit = b.suit;
  a.digit = b.digit;     
}
bool small(Card a, Card b) {
  return a.digit < b.digit;     
}   
void find() {
  int a, b;
  bool doit = false;
  for (a = 0; a < 4; ++a) {
    for (b = a + 1; b < 5; ++b)
      if (unsorted[a].suit - 'A' == unsorted[b].suit - 'A') {
        doit = true;
        break;
      }
    if (doit) break;
  }
  int c = (unsorted[a].digit - unsorted[b].digit + 13) % 13;
  if (c > 6) {
    a += b;
    b = a - b;
    a = a - b;
    c = (unsorted[a].digit - unsorted[b].digit + 13) % 13;      
  }
  
  assign(sorted[0], unsorted[a]);
  assign(sorted[1], unsorted[b]);        
  Card mid[3];
  int count = 0;
  for (int d = 0; d < 5; ++d)
    if (d != a && d != b)
      assign(mid[count++], unsorted[d]);
  Card temp;    
  if (!small(mid[0], mid[1])) {
    assign(temp, mid[0]);
    assign(mid[0], mid[1]);
    assign(mid[1], temp);
  }
  if (!small(mid[1], mid[2])) {
    assign(temp, mid[1]);
    assign(mid[1], mid[2]);
    assign(mid[2], temp);
  }
  if (!small(mid[0], mid[1])) {
    assign(temp, mid[0]);
    assign(mid[0], mid[1]);
    assign(mid[1], temp);
  }
            
  if (c > 3) {
    assign(sorted[c - 2], mid[0]);
    count = 2;
    for (int e = 2; e < 5; ++e)
      if (e != c - 2)
        assign(sorted[e], mid[count--]);     
  } else {
    assign(sorted[c + 1], mid[0]);
    count = 1;
    for (int e = 2; e < 5; ++e)
      if (e != c + 1)
        assign(sorted[e], mid[count++]);         
  }  
}
   
int main()
{
  int test;
  std::cin >> test;
  for (int c = 1; c <= test; ++c) {
    std::string s;
    for (int d = 0; d < 5; ++d) {
      sorted[d].digit = 0;
      sorted[d].suit = 'H';
      std::cin >> s;
      if (s.length() == 3) {
        unsorted[d].digit = 10 + s[1] - '0';
        unsorted[d].suit = s[2];
      } else {
        if (s[0] == 'J')
          unsorted[d].digit = 11;
        else if (s[0] == 'Q')
          unsorted[d].digit = 12;
        else if (s[0] == 'K')
          unsorted[d].digit = 13;
        else if (s[0] == 'A')
          unsorted[d].digit = 1;
        else
          unsorted[d].digit = s[0] - '0';
        unsorted[d].suit = s[1];
      }
    }
    
    find(); 
    std::cout << "Problem " << c << ":";
    for (int e = 0; e < 5; ++e) {
      std::cout << " ";
      if (sorted[e].digit == 13) 
        std::cout << "K";
      else if (sorted[e].digit == 12) 
        std::cout << "Q";
      else if (sorted[e].digit == 11)
        std::cout << "J";
      else if (sorted[e].digit == 1)
        std::cout << "A";
      else 
        std::cout << sorted[e].digit;
      std::cout << sorted[e].suit;
    }
    std::cout << std::endl;         
  }
  //scanf("%d", &test); 
  return 0;
}


你可能感兴趣的:(sicily 1018. A Card Trick)