[Explanations] UVA1603 undermine square Square Destroyer

Is a heuristic search and bit operations, pruning of hybrid topic.

To learn search, the search algorithm is very important. Those players are very powerful search playing well. (By Instructor Li)

Topic analysis

  • First, \ (n≤5 \) , and the number of sides is \ (2N (N +. 1) ≤60 \) . Bit operation can be optimized in such small data.

  • Heuristic search, design evaluation function \ (G (the X-) \) . It requires less than the real price. The following is a method:

  • For each square, delete all of its edges. Repeat this operation does not know the square. The number of operations is valued

  • However, this is not sufficient merely had lost this title. Also it needs to be optimized.

Judgment Square

  • Derivation look on paper, or directly to the law, you can get:

  • If a number is placed horizontally matches \ (X_0 \) ,

  • \ (X_0 \) lower left \ (L \) match and are: $ X_i = X + (2i -1) N + i - 1, (0 <i <L) $.
  • Then the left edge of the square to determine the right edge of the left margin is numbered plus side length.
  • Pretreatment all square, and in ascending order. The reason behind will say
  • In the DFS function in this way reduces the cost to determine the square

Bit computing skills

  • With == unsigned long long == sides number stored a square.

  • Using == & ==, == | == operator to complete the determination whether there is a square, and other operations on the side to increase a state. Specific implementation is

  • #define Mark(X,K) (X=X|((Ull)1<<((K)-1)))
    #define Del(X,K) (X&(~((Ull)1<<((K)-1))))
    #define Check(X,K) (X&(1<<((K)-1)))
  • The role of three macro definitions are: first mark number == == K == X == bit, and delete tags and check for marks.

Less branches

  • From the square pretreatment, the selection of a minimum of a complete enumeration remove its edges.
  • Because the front of the square has been incomplete, then you do not have to struggle. And because small to large order, a branch of the search tree will be less.
  • Using iterative deepening.

Attach part of the code

  • Pretreatment squares: The following code == X == returns to the initial order == K == a side length of a square. And starting the preservation square side length.

    Ull Get (int X , int K) {
      Ull Ans = 0 ;
      int Dlt = K * ((N << 1) + 1) ;
      for (int i = X ; i < X + K ; ++ i) Mark (Ans , i) , Mark (Ans , Dlt + i) ;
      for (int i = 1 ; i <= K; ++ i) 
          Mark (Ans , X + (2*i-1) * N + i - 1) , Mark (Ans ,X + (2*i-1) * N + i - 1 + K) ;
      return Ans ;
    }
  • Evaluation function: removal of the entire square operation using a bit from one state:

    int G (Ull X) {
      int Ans = 0 ;
      for (int i = 1 ; i <= Cnt ; ++ i) {
          if( (S[i] & X) == S[i]) {
              ++ Ans ;
              X = X & (~S[i]) ;
          }
      }
      return Ans ;
    }
  • Search: Because preliminary work done, the internal search function is very simple.

    void DFS (Ull X , int Stp , int Des) {
    
      int Now = G(X) ;
      if (Now + Stp > Ans) return ;
      if (Now == 0 || Fl) {
          Fl = true ;
          return ;
      }
    
    while ((S[Des] & X) != S[Des]) ++ Des ;
    for (int i = F[Des] ; i < F[Des] + Len[Des] ; ++ i) {
          if (Check (X , F[Des]))DFS (Del (X , F[Des]) , Stp + 1 , Des + 1) ;
          if (Check (X , Len[Des] * ((N << 1) + 1) + i))
                DFS (Del ( X , Len[Des] * ((N << 1) + 1) + i) , Stp + 1 , Des + 1);
      }
    for (int i = 1 ; i <= Len[Des]; ++ i) {
      if (Check (X , F[Des] + (2*i-1) * N + i - 1))
              DFS( Del (X , F[Des] + (2*i-1) * N + i - 1) , Stp + 1 , Des + 1) ;
      if (Check (X , F[Des] + (2*i-1) * N + i - 1 + Len[Des])) 
              DFS (Del (X , F[Des] + (2*i-1) * N + i - 1 + Len[Des] ), Stp + 1 , Des + 1) ;
      }
    }

Note Empty Array

Guess you like

Origin www.cnblogs.com/bj2002/p/11367518.html