SOJ 1018. A Card Trick
题目大意:一张卡牌由value和suit决定。value的范围(从小到大)是A,2,3,4,5,6,7,8,9,10,J,Q,K。suit的范围(从小到大)是C,D,H,S。
两张牌比较大小:value较小的牌较小,若value值相等,suit较小的牌较小。
给出五张牌,要求对五张牌进行排列,以满足某种要求:第一张牌和第二张牌的suit要求相同,从后三张牌中选择最小的牌,获得它的位置pos_min(1,2或3),后三张牌除去最小的牌剩余的两张牌如果不是从小到大有序的则addition = 3,否则addition = 0. 第二张牌的value + pos_min + addition(若大于13则三者和减13)等于第一张牌的value。
解题思路:模拟。结构化牌,包括value和suit两个元素。对五张牌进行全排列,对每一个排列检查是否满足要求,找到第一个满足要求的排列即可。
代码如下:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 8 class Card { 9 public: 10 friend istream & operator>>(istream &is, Card &card) { 11 string text; 12 is >> text; 13 // for (int i = 0; i < text.size(); ++i) text[i] = toupper(text[i]); 14 card.value = atoi(text.c_str()); 15 // 获取value 16 if (card.value == 0) { // 没有数字开头 17 if (text[0] == 'J') { 18 card.value = 11; 19 } else if (text[0] == 'Q') { 20 card.value = 12; 21 } else if (text[0] == 'K') { 22 card.value = 13; 23 } else if (text[0] == 'A') { 24 card.value = 1; 25 } else { 26 while (true); 27 } 28 } 29 // 获取suit 30 /*if (text.back() == 'C') { 31 card.suit = 1; 32 } else if (text.back() == 'D') { 33 card.suit = 2; 34 } else if (text.back() == 'H') { 35 card.suit = 3; 36 } else if (text.back() == 'S') { 37 card.suit = 4; 38 }*/ 39 if (text[text.size()-1] == 'C') { 40 card.suit = 1; 41 } else if (text[text.size()-1] == 'D') { 42 card.suit = 2; 43 } else if (text[text.size()-1] == 'H') { 44 card.suit = 3; 45 } else if (text[text.size() - 1] == 'S') { 46 card.suit = 4; 47 } else { 48 while (true); 49 } 50 return is; 51 } 52 53 friend ostream & operator<<(ostream &os, const Card &card) { 54 if (card.value == 1) os << "A"; 55 else if (card.value < 11) os << card.value; 56 else if (card.value == 11) os << "J"; 57 else if (card.value == 12) os << "Q"; 58 else if (card.value == 13) os << "K"; 59 if (card.suit == 1) os << "C"; 60 else if (card.suit == 2) os << "D"; 61 else if (card.suit == 3) os << "H"; 62 else if (card.suit == 4) os << "S"; 63 return os; 64 } 65 66 bool operator<(const Card &other) const { 67 return (value < other.value) || (value == other.value && suit < other.suit); 68 } 69 int value; 70 int suit; 71 }; 72 73 int main() { 74 int times; 75 const int maxn = 5; 76 Card cards[maxn]; 77 scanf("%d", ×); 78 for (int t = 1; t <= times; ++t) { 79 for (int i = 0; i < maxn; ++i) cin >> cards[i]; 80 sort(cards, cards + maxn); 81 do { 82 if (cards[0].suit != cards[1].suit) continue; 83 int addition; 84 if (cards[2] < cards[3] && cards[2] < cards[4]) { // cards[2] 最小 85 addition = 1; 86 addition += cards[3] < cards[4] ? 0 : 3; 87 } else if (cards[3] < cards[2] && cards[3] < cards[4]) { // cards[3] 最小 88 addition = 2; 89 addition += cards[2] < cards[4] ? 0 : 3; 90 } else if (cards[4] < cards[2] && cards[4] < cards[2]) { 91 addition = 3; 92 addition += cards[2] < cards[3] ? 0 : 3; 93 } 94 if (cards[0].value == (cards[1].value + addition - 1) % 13 + 1) break; 95 } while (next_permutation(cards, cards + maxn)); 96 cout << "Problem " << t << ": "; 97 for (int i = 0; i < maxn; ++i) { 98 cout << cards[i] << (i + 1 == maxn ? "\n" : " "); 99 } 100 } 101 return 0; 102 }