//////////////////////////////////////// ///////
// Maximum number of Bastion hosts
// Use the Backtracking Method (in fact, the modification of the n queen's problem) + brute-force a removal
# Include <iostream>
# Include <math. h>
Using namespace STD;
Char A [5] [5];
// Bastion class for convenient access to members
Class blockhouses
{
Friend int nblock (INT );
PRIVATE:
Bool place (int K );
Bool place2 (int K );
Void backtrack (int t, int lever );
Int N,
** X;
Int Max;
};
// Determine whether a bastion host can be placed at this location
Bool blockhouses: Place (int K)
{
Int I, J;
Bool flags = 1;
If (k =-1 | K = 0) return 1; // In the following call, K may be less than 0
For (I = 1; I <K; I ++)
{
// When the number of columns is equal, determine whether there is a wall between X [I] and X [K ].
If (X [I] [2] = x [k] [2])
{
Flags = 0;
For (j = x [I] [1] + 1; j <X [k] [1]; j ++)
{
If (A [J] [x [I] [2] = 'X ')
Flags = 1;
}
If (! Flags) return 0;
}
}
Return flags;
}
// Because the number of rows is not determined, add one more row
Bool blockhouses: place2 (int K)
{
Int J;
// 1 can be returned immediately for different rows
If (X [k-1] [1]! = X [k] [1]) return 1;
// If the remaining rows are the same, determine whether there is a wall in the middle.
For (j = x [k-1] [2] + 1; j <X [k] [2]; j ++)
If (A [x [k] [1] [J] = 'X ')
Return 1;
Return 0;
}
// Recursive Backtracking Function
// T records the currently placed bastion host. The lever is the current number of rows,
// Note records the number of Bastion hosts temporarily placed in the row to modify t
Void blockhouses: backtrack (int t, int lever)
{
Int I, j, note;
If (lever> N)
{
If (t-1> MAX)
Max = T-1;
}
Else
{
// This loop indicates entering the branches of the N-tree (using different elements of the same row as the child of each element of the previous row)
For (I = 1; I <= N; I ++)
{
Note = 0;
// This loop is used to calculate the lever line.
For (j = I; j <= N; j ++)
{
If (A [lever] [J]! = 'X ')
{
X [T] [1] = lever;
X [T] [2] = J;
If (place2 (t ))
{
T ++;
Note ++;
}
}
}
// When the pull into the T-1 and T-2 bastion meet the requirements of the next layer (ROW) Search
If (Place (t-2) & PLACE (t-1 ))
Backtrack (T, lever + 1 );
T-= note;
// Note that when the lever row is not pulled into the bastion host, let it perform a further search,
// Connect the lever-1 layer to the lever + 1 Layer
If (t-1> 0) & (X [T-1] [1] <lever ))
Backtrack (T, lever + 1 );
}
}
}
// This function is set to call Members.
Int nblock (int n)
{
Int I, J;
Blockhouses X;
X. max = 0;
X. n = N;
Int ** P = new int * [N * n + 1];
// P [] (that is, X []) uses P [] [1] and P [] [2] to record the number of rows and columns of the bastion host.
For (I = 0; I <= N * n; I ++) P [I] = new int [3];
For (I = 0; I <= N * n; I ++)
For (j = 1; j <= 2; j ++)
P [I] [J] = 0;
X. x = P;
X. Backtrack (1, 1 );
For (I = 0; I <= N * n; I ++) Delete [] P [I]; // release the Array
Return X. Max;
}
Int main ()
{
Int N;
While (CIN> N & n! = 0)
{
Int I, J;
For (I = 1; I <= N; I ++)
For (j = 1; j <= N; j ++)
Cin> A [I] [J];
Cout <nblock (n) <Endl;
}
Return 0;
}