题意:
你的任务是模拟一种叫「Accordian」的纸牌游戏,他的游戏规则如下:
一副扑克牌有52张牌,首先把纸牌一张一张由左到右排好(不能有重叠,所以共有52堆牌,每堆一张),当某一张牌与他左边那张牌或者左边的第三张牌有「Match」的时候,就把这张牌移到那张牌上面去。在这里两张牌「Match」指的是这两张牌的花色(suit)或者点数(rank)一样。当你做了一个移动之后,要察看是否还可以做其他的移动。在任何时间,只有最上面那张牌可以被移动。如果因为移动一张牌使得产生一个空格(也就是被移动的那堆牌只有一张牌),你必须把右边所有的牌堆往左移一格。如此不断的寻找可移动的牌,直到没有一张牌可以移动游戏就结束了。
在选择可以移动的牌的时候可能有些状况会发生。如果有两张牌都可以移动,你应该要移动最左边的那张牌。当一张牌可以被移动到左边一格,或左边三格的时候,你必须移动到左边三格
解法:
纯模拟,外层用STL set,内层用STL stack,然后就是各种调用,各种迭代器~
代码:
1# include <list>
2# include <vector>
3# include <cstdio>
4# include <algorithm>
5using namespace std;
6list<vector<pair<char,char> > > l;
7int main()
8{
9 vector<pair<char,char> >t;
10 while(true)
11 {
12 char tmp[5];
13 scanf("%s",tmp);
14 if(tmp[0]=='#') break;
15 t.clear();
16 l.clear();
17 t.push_back(pair<char,char>(tmp[0],tmp[1]));
18 l.push_back(t);
19 for(int i=1;i<52;i++)
20 {
21 t.clear();
22 scanf("%s",tmp);
23 t.push_back(pair<char,char>(tmp[0],tmp[1]));
24 l.push_back(t);
25 }
26 while(true)
27 {
28 bool flag=false;
29 for(list<vector<pair<char,char> > >::iterator i=l.begin();i!=l.end()&&!flag;)
30 {
31 int count=0;
32 bool remove=false;
33 list<vector<pair<char,char> > >::iterator i3=i;
34 while(i3!=l.begin()&&count<3)
35 {
36 count++;
37 i3--;
38 }
39 if(count==3&&(i3->back().first==i->back().first||i3->back().second==i->back().second))
40 {
41 i3->push_back(i->back());
42 i->pop_back();
43 if(i->empty()) i=l.erase(i),remove=true;
44 flag=true;
45 }
46 else
47 {
48 i3=i;
49 if(i3!=l.begin())
50 {
51 i3--;
52 if(i3->back().first==i->back().first||i3->back().second==i->back().second)
53 {
54 i3->push_back(i->back());
55 i->pop_back();
56 if(i->empty()) i=l.erase(i),remove=true;
57 flag=true;
58 }
59 }
60 }
61 if(!remove) i++;
62 }
63 if(!flag) break;
64 }
65 printf("%d piles remaining:",l.size());
66 for(list<vector<pair<char,char> > >::iterator i=l.begin();i!=l.end();i++)
67 printf(" %d",i->size());
68 printf("\n");
69 }
70}
71