Los P1312 Mayan ancient game (dfs + pruning)

Topic Link

This question and Tetris like

Obviously, we can see that this is a dfs, however, we need a few Pruning:

1. If only one or two squares of the same color, then exit

2. The same blocks without a swap

3. Note that the priority, priority to change the left to the right

But this kind of problem so it would be finished

Apparently, not so simple: pruning clear, are you sure you can write it (this is the longest I've written dfs)

Then talk about my program architecture:

init function: input, storing data

fall function: Analog drop box

printans function: Output answer

clear function: clear the board

isempty function: determining whether the air

judge function: pruning 1

dfs function: search

Here is the code, read the above words, the code also has comments

 

 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int N = 5;
  5 const int M = 7;
  6 
  7 int maxstep, chess[N][M];
  8 int cnt[11];
  9 int answer[5][3];
 10 
 11 void init()
 12 {
 13     cin>>maxstep;
 14     for(int i=0 ; I <N; I ++ )
 15      {
 16          int J = 0 , X;
 . 17          CIN >> X;
 18 is          the while (X =! 0 )
 . 19          {
 20 is              Chess [I] [J] = X;
 21 is              J ++ ;
 22 is              CIN >> X;
 23 is          }
 24      }
 25  }
 26 is  
27  void fall ()     // after clearing drop box 
28  {
 29      for ( int I =0; i<N; i++)
 30         for(int j=0; j<M; j++)
 31         {
 32             if(chess[i][j]!=0)
 33                 continue;
 34             int k;
 35             for(k=j+1; k<M; k++)
 36                 if(chess[i][k]!=0)
 37                 {
 38                     swap(chess[i][j],chess[i][k]);
 39                     break;
 40                 }
 41             if(k==M)
 42                 break;
 43         }
 44 }
 45 
 46 void printans()     //输出
 47 {
 48     for(int i=0; i<maxstep; i++)
 49         printf("%d %d %d\n",answer[i][0],answer[i][1],answer[i][2]);
 50     return;
 51 }
 52 
 53 bool clear()        //清除棋盘
 54 {
 55     bool empty[N][M];
 56     memset(empty,false,sizeof(empty));
 57     for(int i=0; i<N-2; i++)
 58         for(int j=0; j<M; j++)
 59             if(chess[i][j]!=0 && chess[i][j]==chess[i+1][j] 
 60                 && chess[i+1][j]==chess[i+2][j]) {
 61                     empty[i][j]=empty[i+1][j]=empty[i+2][j]=true;
 62                 }
 63                 
 64 
 65     for(int i=0; i<N; i++)
 66         for(int j=0; j<M-2; j++)
 67             if(chess[i][j]!=0 && chess[i][j]==chess[i][j+1]
 68                 && chess[i][j+1]==chess[i][j+2]) {
 69                     empty[i][j]=empty[i][j+1]=empty[i][j+2]=true;
 70                 }
 71 
 72     bool res=false;
 73     for(int i=0; i<N; i++)
 74         for(int j=0; j<M; j++)
 75             if(empty[i][j])
 76             {
 77                 chess[i][j]=0;
 78                 res=true;
 79             }
 80     return res;
 81 }
82  
83  BOOL isEmpty ()       // determines whether or not the board blank 
84  {
 85      for ( int I = 0 ; I <N; I ++ )
 86          for ( int J = 0 ; J <M; J ++ )
 87              IF (Chess [I] [J] =! 0 )
 88                  return  to false ;
 89      return  to true ;
 90  }
 91 is  
92  BOOL Judge ()         // determines whether the number of blocks of one color is 1 or 2 
93  {
 94      Memset (CNT,0,sizeof(cnt));
 95     for(int i=0; i<N; i++)
 96         for(int j=0; j<M; j++)
 97             cnt[chess[i][j]]++;
 98     for(int i=1; i<=10; i++)
 99         if(cnt[i]==1||cnt[i]==2)
100             return false;
101     return true;
102 }
103  
104  BOOL DFS ( int STEP)       // search 
105  {
 106      IF (isEmpty ())        // find a set of solutions 
107      {
 108          printans ();
 109          return  to true ;
 110      }
 111      IF (STEP> = MaxStep Judge ||! ())      // prune the end condition 
112          return  to false ; 
 113  
114      int now [N] [M];       // record the current state, when a back 
115      for ( int I = 0; I <N; I ++)       // copy board 
1 16          for ( int J = 0 ; J <M; J ++ )
 117              now [I] [J] = Chess [I] [J];
 1 18  
119      for ( int I = 0 ; I <N; I ++ )
 120          for ( int J = 0 ; J <M; J ++)       // enumeration each block 
121          {
 122              // right 
123              IF (I = N-! . 1 && Chess [I] [ J]! = 0 && Chess [I] [J]! = Chess [I + . 1 ] [J])
 124             {
125                 swap(chess[i][j], chess[i+1][j]);
126                 answer[step][0]=i;
127                 answer[step][1]=j;
128                 answer[step][2]=1;
129                 fall();
130                 while(clear())
131                     fall();
132                 if(dfs(step+1))
133                     return true;
134             }
135 
136             for(int k1=0; k1<N; k1++)
137                 for(int k2=0; k2<M; k2++)
138                     chess[k1][k2]=now[k1][k2];
139 
140             //左移
141             if(i!=0 && chess[i][j]!=0 && chess[i-1][j]==0)
142             {
143                 swap(chess[i][j], chess[i-1][j]);
144                 answer[step][0]=i;
145                 answer[step][1]=j;
146                 answer[step][2]=-1;
147                 fall();
148                 while(clear())
149                     fall();
150                 if(dfs(step+1))
151                     return true;
152             }
153 
154             for(int k1=0; k1<N; k1++)
155                 for(int k2=0; k2<M; k2++)
 156                      Chess [K1] [K2] = now [K1] [K2];
 157          }
 158      return  to false ;
 159  }
 160.  
161  / * 
162  searches + prune 
 163  prune Principle:
 164 is  1, the exchange of two blocks of the same color Pointless.
165  2, if the number of blocks of one color is 1 or 2, the current situation has no solution.
166  3, since the minimum requirements lexicographic solution, only if it is a left block attempt is left empty
 167  (if there are blocks left, then the search when i-1 columns to the right, and left in the i-th column when are equivalent, it is possible to prune) 
 168  * /  
169  int main ()
 170.  {
 171 is      iOS :: sync_with_stdio ( to false );
 172      cin.tie ( 0);
173     
174     init();
175     if(!dfs(0))
176         cout<<-1<<endl;
177     return 0;
178 }

 

Added: Speaking of Tetris, I want to up USACO of this question , interested students can do do

 

Guess you like

Origin www.cnblogs.com/jasonownblog/p/12548189.html