<cf>Solitaire(DFS or DP)

B. Solitaire
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A boy named Vasya wants to play an old Russian solitaire called "Accordion". In this solitaire, the player must observe the following rules:

 

  • A deck of n cards is carefully shuffled, then all n cards are put on the table in a line from left to right;
  • Before each move the table has several piles of cards lying in a line (initially there are n piles, each pile has one card). Let's number the piles from left to right, from 1 to x. During one move, a player can take the whole pile with the maximum number x (that is the rightmost of remaining) and put it on the top of pile x - 1 (if it exists) or on the top of pile x - 3 (if it exists). The player can put one pile on top of another one only if the piles' top cards have the same suits or values. Please note that if pilex goes on top of pile y, then the top card of pile x becomes the top card of the resulting pile. Also note that each move decreases the total number of piles by 1;
  • The solitaire is considered completed if all cards are in the same pile.

 

Vasya has already shuffled the cards and put them on the table, help him understand whether completing this solitaire is possible or not.

Input

The first input line contains a single integer n (1 ≤ n ≤ 52) — the number of cards in Vasya's deck. The next line contains n space-separated strings c1, c2, ..., cn, where string ci describes the i-th card on the table. Each string ci consists of exactly two characters, the first one represents the card's value, the second one represents its suit. Cards on the table are numbered from left to right.

A card's value is specified by one of these characters: "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A". A card's suit is specified by one of these characters: "S", "D", "H", "C".

It is not guaranteed that the deck has all possible cards. Also, the cards in Vasya's deck can repeat.

Output

On a single line print the answer to the problem: string "YES" (without the quotes) if completing the solitaire is possible, string "NO" (without the quotes) otherwise.

Sample test(s)
input
4
2S 2S 2C 2C
output
YES
input
2
3S 2C
output
NO
Note

In the first sample you can act like that:

  • put the 4-th pile on the 1-st one;
  • put the 3-rd pile on the 2-nd one;
  • put the 2-nd pile on the 1-st one.

 

In the second sample there is no way to complete the solitaire.

我用的是DFS

AC code:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <map>
 4 using namespace std;
 5 
 6 string cur[53];//记录一沓牌当前状态的value和suit
 7 map <string,int> flag;
 8 int n;
 9 bool YES;
10 
11 void DFS(int idx)
12 {
13     if(idx==n-1)
14     {
15         YES=1;
16         return ;
17     }
18     if(idx+1<n && (cur[idx+1][0]==cur[idx][0]||cur[idx+1][1]==cur[idx][1]))
19     {
20         string pre=cur[idx+1];//pre一定要定义为此处的局部变量!!!这样才不影响后面的pre
21         cur[idx+1]=cur[idx];
22         /*vis串记录cur[idx+1]及其以后的牌的状况,当这些牌的情况是第一次出现时,进行标记,
23         如果已有标记,表明之前这种情况的牌已出现且是不能成功进行下去的(不能成功
24         进行下去才会回溯,因而才会再次遇到),那么现在也必定如是。故直接return。*/
25         string vis=cur[idx+1];
26         for(int i=2;i+idx<n;i++)
27             vis+=cur[idx+i];
28         if(flag[vis]==0)
29         {
30             flag[vis]=1;
31             DFS(idx+1);
32         }
33         if(YES) return ;
34         cur[idx+1]=pre;
35     }
36     if(idx+3<n && (cur[idx+3][0]==cur[idx][0]||cur[idx+3][1]==cur[idx][1]))
37     {
38         string pre=cur[idx+3];//pre一定要定义为此处的局部变量!!!这样才不影响前面的pre
39         cur[idx+3]=cur[idx];
40         /*注意这里虽然是idx+3的情况,但vis仍由cur[idx+1]开始加到cur[n-1]而非由cur[idx+3]
41         开始,因为在这种情况,cur[idx]是跳过cur[idx+1],cur[idx+2]加在cur[idx+3]上的,故
42         cur[idx+1],cur[idx+2]还未处理,还是需要考虑的因素。*/
43         string vis=cur[idx+1];
44         for(int i=2;i+idx<n;i++)
45             vis+=cur[idx+i];
46         if(flag[vis]==0)
47         {
48             flag[vis]=1;
49             DFS(idx+1);
50         }
51         if(YES) return ;
52         cur[idx+3]=pre;
53     }
54     return ;
55 }
56 
57 int main()
58 {
59     while(scanf("%d",&n)!=EOF)
60     {
61         YES=0;
62         //倒着输入,便于后续程序编写
63         for(int i=n-1;i>-1;i--)
64         {
65             cin>>cur[i];
66         }
67         DFS(0);
68         if(YES) puts("YES");
69         else puts("NO");
70     }
71     return 0;
72 }

 

 

再贴一个代码的原型。。。纪念我过这题的轰烈悲壮。。。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <memory.h>
  5 #include <map>
  6 using namespace std;
  7 
  8 
  9 
 10 //string pre;//一沓牌上一状态的value和suit
 11    // string pre_s;//一沓牌上一状态的suit
 12 string cur[53];//一沓牌当前状态的value和suit
 13    // string cur_s;//一沓牌当前状态的suit
 14    // int pre;//记录这一沓牌上一状态中最上层一张牌的编号
 15    // int cur;//记录这一沓牌当前状态中最上层一张牌的编号
 16 
 17 
 18 
 19 map <string,int> flag;
 20 //string s;
 21 int n;//cnp is standing for "current numbers of piles"
 22 bool YES;//flag用于判断是否YES
 23 //int t;
 24 
 25 void DFS(int idx)
 26 {//cout<<idx<<" ";
 27    //if(t++>250) return ;
 28 
 29    // ct<<cnp<<" ";
 30    /* if(cnp==1)
 31     {//ct<<1<<" ";
 32         flag=1;
 33         return ;
 34     }*/
 35    // if(p[idx+1].cur_v!=p[idx].cur_v && p[idx+1].cur_s!=p[idx].cur_s && p[idx+3].cur_v!=p[idx].cur_v && p[idx+3].cur_s!=p[idx].cur_s)
 36   //  {ct<<2<<" ";
 37   //      return ;
 38   //  }
 39 
 40         if(idx==n-1)
 41         {//ct<<1<<" ";
 42             //cout<<2;
 43             YES=1;
 44             return ;
 45         }
 46         if(idx+1<n && (cur[idx+1][0]==cur[idx][0]||cur[idx+1][1]==cur[idx][1]))
 47         {//ct<<3<<" ";
 48           //  cout<<1<<cur[idx]<<"--"<<cur[idx+1]<<" ";
 49 
 50             string pre=cur[idx+1];//pre一定要定义为此处的局部变量!!!这样才不影响后面的pre
 51            // p[idx+1].pre_s=p[idx+1].cur_s;
 52             cur[idx+1]=cur[idx];
 53            // vis.index=idx+1;
 54             string vis=cur[idx+1];
 55             for(int i=2;i+idx<n;i++)
 56                 vis+=cur[idx+i];
 57            // if(idx+2<n) vis.str+=cur[idx+2];
 58            // for(int i=0;i<11;i++) cout<<cur[i]<<" ";cout<<endl;
 59            // p[idx+1].cur_v=p[idx].cur_v;
 60            // vis[idx]=1;
 61            // cnp--;
 62             //s.clear();
 63            // s[0]=idx+'0';cout<<s[0]<<" ";
 64            // s+=p[idx+1].cur;cout<<s<<" ";
 65             if(flag[vis]==0)
 66             {//cout<<"#"<<" ";
 67                 flag[vis]=1;
 68                 DFS(idx+1);
 69             }
 70             if(YES) return ;
 71            // vis[idx]=0;
 72             cur[idx+1]=pre;
 73           //  p[idx+1].cur_v=p[idx+1].pre_v;
 74           //  cnp++;
 75         }
 76         if(idx+3<n && (cur[idx+3][0]==cur[idx][0]||cur[idx+3][1]==cur[idx][1]))
 77         {//ct<<4<<" ";
 78            //cout<<3<<cur[idx]<<"--"<<cur[idx+3]<<" ";
 79             string pre=cur[idx+3];//pre一定要定义为此处的局部变量!!!这样才不影响前面的pre
 80            // p[idx+1].pre_s=p[idx+1].cur_s;
 81             cur[idx+3]=cur[idx];
 82           //  vis.index=idx+3;
 83             string vis=cur[idx+1];
 84             for(int i=2;i+idx<n;i++)
 85                 vis+=cur[idx+i];
 86            // vis.str=cur[idx+3]+cur[idx+2]+cur[idx+1];
 87            // if(idx-1>-1) vis.str+=cur[idx-1]
 88            // for(int i=0;i<11;i++) cout<<cur[i]<<" ";cout<<endl;
 89           //  vis[idx]=1;
 90           //  cnp--;
 91            // s.clear();
 92            // s[0]=idx+'0';
 93          //   s+=p[idx+3].cur;cout<<s<<" ";
 94             if(flag[vis]==0)
 95             {//cout<<"*"<<" ";
 96                 flag[vis]=1;
 97                 DFS(idx+1);
 98             }
 99             if(YES) return ;
100           //  vis[idx]=0;
101             cur[idx+3]=pre;
102           //  p[idx+3].cur_v=p[idx+3].pre_v;
103          //   cnp++;
104         }
105     return ;
106 }
107 
108 int main()
109 {
110     while(scanf("%d",&n)!=EOF)
111     {
112        // cnp=n;
113        YES=0;
114       //  memset(vis,0,sizeof(vis));
115         //倒着输入,便于后续程序编写
116         for(int i=n-1;i>-1;i--)
117         {
118             cin>>cur[i];
119            // p[i].pre=p[i].cur;
120            // p[i].pre_v=p[i].cur_v;
121         }
122         DFS(0);
123         if(YES) puts("YES");
124         else puts("NO");
125     }
126     return 0;
127 }
128 //25
129 //AD 5S KH AH KS

 



posted on 2012-07-29 10:31  铁树银花  阅读(311)  评论(0编辑  收藏  举报

导航