模拟游戏,规则如下
把卡牌一张接一张,从左到右依次摊开,不可以重叠,每当某张卡片和左边(左边第三张)卡片匹配,
它就能放到另外一张卡片上,匹配的规则是他们有一样的级别或者花色,
在每次移动完成以后,还需要再次检查这次移动后是否会造成其他可能的移动,
只有每一叠卡片最上面那张能够移动,如果一叠牌被移空,应该立即将右边各叠整体向左移动,
补上这个空隙,依次将牌发完,并尽可能的向左合并,如果最后只剩下一叠牌,则游戏胜利
多玩几次可能会出现这样的局面,
有俩个卡片可以移动,你应该采取的策略是移动最左边的卡片
如果一张卡片能够移动到左边第一个位置和第三个位置,将它移动到第三个位置上
输入到程序的数据指出了一副牌发出的顺序,输入包括俩行,
每一行包含26个卡片,每个卡片用一个空格隔开,
输入文件的最后一行包含一个#作为它的第一个字符,
一张牌代表俩个字符单元,
第一个字符是面值(A=Ace,2-9,T=10,J=Jack,Q=Queen,K=King)
第二个字符是它的花色,(C=Clubs(梅花),D=Diamonds(钻石),H=Hearts(红心),S=Spades(黑桃))
每俩行(定义了一副52张牌)产生一个输出行,
每个输出行输出经过游戏后,剩下的叠数,每叠牌中的数目
AC代码如下,适用列表,一个Head数组
将tail指针指向数组位置绝对是噩梦
1 #include <iostream> 2 #include<stdio.h> 3 using namespace std; 4 5 struct Node 6 { 7 Node* next = NULL; 8 Node* pre = NULL; 9 //指向最后一个位置,不能是数组的位置 10 Node* tail = NULL; 11 char suit; 12 char face; 13 int total; 14 }; 15 bool compareNode(const Node* node1, const Node* node2) 16 { 17 18 return (node1->face == node2->face) || (node1->suit == node2->suit); 19 } 20 /** 21 * 22 *get a head that node can link. 23 *if can not find,return NULL 24 */ 25 int findSuitableHead(Node* const heads, int total, Node* const node) 26 { 27 int index = -1; 28 while (true) 29 { 30 bool fh = false; 31 if (total >= 3) 32 { 33 //可以找前面第三个 34 Node hNode = heads[total - 3]; 35 if (compareNode(hNode.tail, node)) 36 { 37 total -= 3; 38 index = total; 39 fh = true; 40 } 41 } 42 if (!fh && total >= 1) 43 { 44 //前三个位置不合适,前一个位置 45 Node hNode = heads[total - 1]; 46 if (compareNode(hNode.tail, node)) 47 { 48 total -= 1; 49 fh = true; 50 index = total; 51 } 52 } 53 if (!fh) 54 { 55 return index; 56 } 57 } 58 } 59 void reMegerNode(Node* const heads, int& total, int sIndex) 60 { 61 while (true) 62 { 63 bool hasResize = false; 64 for (int i = sIndex + 1; i < total; i++) 65 { 66 int j = findSuitableHead(heads, i, (heads + i)->tail); 67 if (j != -1) 68 { 69 //可以合并 70 Node* nHead = heads + j; 71 //这句话fb50 72 // Node mNode = heads[i]; 73 Node* mNode = new Node; 74 *mNode = heads[i]; 75 76 bool nm = heads[i].total == 1 ? true : false; 77 if (nm) 78 { 79 //mNode is head 80 mNode->total = 0; 81 mNode->tail = NULL; 82 nHead->tail->next = mNode; 83 mNode->pre = nHead->tail; 84 nHead->tail = mNode; 85 nHead->total++; 86 total--; 87 for (int k = i; k < total; k++) 88 heads[k] = heads[k + 1]; 89 90 Node n; 91 heads[total] = n; 92 } 93 else 94 { 95 //不是表头 96 heads[i].total--; 97 Node* tail = heads[i].tail; 98 Node* pre = tail->pre; 99 heads[i].tail = pre; 105 pre->next = NULL; 106 tail->pre = NULL; 107 nHead->tail->next = tail; 108 tail->pre = nHead->tail; 109 nHead->tail = tail; 110 nHead->total++; 111 } 112 sIndex = j == 0 ? 0 : j - 1; 113 hasResize = true; 114 break; 115 } 116 } 117 if (!hasResize) 118 { 119 return; 120 } 121 } 122 123 } 124 void mergeNode(Node* const heads, int& total, Node* node) 125 { 126 int sIndex = findSuitableHead(heads, total, node); 127 if (sIndex == -1) 128 { 129 //new head 130 node->total = 1; 131 heads[total] = *node; 132 heads[total].tail = node; 133 total++; 134 } 135 else 136 { 137 heads[sIndex].tail->next = node; 138 node->pre = heads[sIndex].tail; 139 heads[sIndex].tail = node; 140 heads[sIndex].total++; 141 reMegerNode(heads, total, sIndex); 142 } 143 } 144 void print(Node* const heads, int total) 145 { 146 if(total!=1) 147 cout << total << " piles remaining:"; 148 else 149 cout << total << " pile remaining:"; 150 for (int i = 0; i < total; i++) 151 { 152 cout << " " << heads[i].total; 153 } 154 cout << endl; 155 } 156 157 int main() 158 { 159 //freopen("d:\\1.txt", "r", stdin); 160 char c1; 161 while (true) 162 { 163 Node* node = new Node; 164 cin >> c1; 165 if (c1 == ‘#‘) 166 { 167 return 0; 168 } 169 node->face = c1; 170 cin >> node->suit; 171 int total = 0; 172 Node heads[52]; 173 node->total = 1; 174 heads[total++] = *node; 175 heads[total - 1].tail = node; 176 for (int i = 0; i < 51; i++) 177 { 178 node = new Node; 179 cin >> node->face >> node->suit; 180 mergeNode(heads, total, node); 181 } 182 print(heads, total); 183 } 184 }
时间: 2024-10-05 06:48:35