https://vjudge.net/problem/UVA-127
题意:
按从左至右的顺序发牌,并摆成一行,发牌不要相互重叠。游戏中一旦出现任何一张牌与它左边的第一张或第三张“匹配”,即花色或点数相同,则须立即将其移动到那张牌上面。如果牌被移动后又出现了上述情况,则需再次向左移动。每叠牌只能移动最上面的一张。如果一叠牌被移空,应该立即将右边各叠整体向左移动,补上这个空隙。依次将整副牌都发完,并不断的向左合并。输出最后的牌堆数以及各牌堆的牌数。
思路:
代码虽然写着挺长,但题目很简单。用栈解决。
每个牌堆用一个栈来表示,如果牌堆空了也不需要左移啥的,如果栈空则跳过它就好了。每次移动之后,需要重新去前面的那个牌堆开始检验。
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<algorithm> 5 #include<stack> 6 using namespace std; 7 8 struct node 9 { 10 char str[3]; 11 }c[55]; 12 13 int main() 14 { 15 //freopen("D:\txt.txt", "r", stdin); 16 while (cin >> c[0].str) 17 { 18 if (c[0].str[0] == '#') break; 19 stack<node> sta[55]; 20 sta[0].push(c[0]); 21 for (int i = 1; i < 52; i++) 22 { 23 cin >> c[i].str; 24 sta[i].push(c[i]); 25 } 26 for (int i = 1; i < 52; i++) 27 { 28 if (sta[i].empty()) continue; //如果第i堆牌为空,继续下一堆 29 int cnt = 0; 30 int t = i - 1; 31 while (t >= 0) 32 { 33 if (!sta[t].empty()) 34 cnt++; 35 if (cnt == 3) break; //找到i左边第3个牌堆 36 t--; 37 } 38 if (cnt==3) 39 { 40 node s1 = sta[t].top(); 41 node s2 = sta[i].top(); 42 if (s1.str[0] == s2.str[0] || s1.str[1] == s2.str[1]) 43 { 44 sta[i].pop(); 45 sta[t].push(s2); 46 i = t-1; 47 continue; //如果和第3个匹配,则不再进行左边第1个的匹配 48 } 49 } 50 t = i - 1; 51 while (t >= 0 && sta[t].empty()) t--; 52 if (t >= 0) 53 { 54 node s1 = sta[t].top(); 55 node s2 = sta[i].top(); 56 if (s1.str[0] == s2.str[0] || s1.str[1] == s2.str[1]) 57 { 58 sta[i].pop(); 59 sta[t].push(s2); 60 i = t-1; //重新去检查第t个牌堆,因为循环最后会i++,所以这里i要等于t-1 61 } 62 } 63 } 64 int num[52]; 65 int cnt = 0; 66 for (int i = 0; i < 52; i++) 67 { 68 if (sta[i].size() != 0) 69 num[cnt++] = sta[i].size(); 70 } 71 cout << cnt << " pile"; 72 if (cnt>1) cout << "s"; 73 cout << " remaining:"; 74 for (int i = 0; i < cnt; i++) 75 cout << " "<< num[i]; 76 cout << endl; 77 } 78 return 0; 79 }