In a game, the square of n * n is colored in the upper left corner each time, and a connected block is all colored. The connected block is defined as four adjacent directions and the color is the same.
Ask for the minimum number of steps, IDA * search.
The important step is to divide the entire square into three parts. The first part is in a connected block with the upper left corner, marked as 1. The second part is different from the connected block color, but adjacent, marked as 2. We can see that the part marked as 2 is our dyeing choice. We will dye the connected block into the color of 2, and then add this square to the connected block.
A * The number of colors in the remaining part of the pruning indicates the minimum number of dyeing times.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <map>
# Include <cstring>
# Include <cmath>
# Include <vector>
# Include <algorithm>
# Include <set>
# Include <string>
# Include <queue>
# Define inf 1 <30
# Define M 60005
# Define N 10005
# Define maxn300005
# Define eps 1e-10
# Define zero (a) fabs (a) <eps
# Define Min (a, B) (a) <(B )? (A) (B ))
# Define Max (a, B) (a)> (B )? (A) (B ))
# Define pb (a) push_back ()
# Define mem (a, B) memset (a, B, sizeof ())
# Define LL long
# Define lson step <1
# Define rson step <1 | 1
# Define MOD 1000000009.
Using namespace std;
Int maze [10] [10];
Int n;
Int way [4] [2] = {, 0,-, 0 };
Int vis [10] [10]; // ID of each node. If it is 1, it indicates that it is connected to the upper left. If it is 2, it indicates that it is not directly connected to the upper left but adjacent to the upper left connected block.
Bool check (int x, int y)
{
If (x <0 | y <0 | x> = n | y> = n) return false;
Return true;
}
Void floodfill (int x, int y, int c)
{
Vis [x] [y] = 1;
For (int I = 0; I <4; I ++)
{
Int tx = x + way [I] [0];
Int ty = y + way [I] [1];
If (! Check (tx, ty) continue;
If (vis [tx] [ty] = 1) continue;
If (maze [tx] [ty] = c) floodfill (tx, ty, c );
Else vis [tx] [ty] = 2;
}
}
// If col is dyed, how many grids will be added to the connected block?
Int get_cnt (int col)
{
Int cnt = 0;
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
If (maze [I] [j] = col & vis [I] [j] = 2)
{
Cnt ++;
Floodfill (I, j, maze [I] [j]);
}
}
}
Return cnt;
}
// Evaluate function, indicating the colors except the connected Blocks
// That is, the minimum number of dyeing times.
Int get_h ()
{
Bool flag [6]; mem (flag, false );
Int cnt = 0;
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
If (vis [I] [j]! = 1 &&! Flag [maze [I] [j])
{
Cnt ++;
Flag [maze [I] [j] = true;
}
}
}
Return cnt;
}
Int depth;
Bool IDAstar (int dep)
{
If (depth = dep) return get_h () = 0;
If (dep + get_h ()> depth) return false;
For (int I = 0; I <6; I ++)
{
Int tmp [10] [10];
Memcpy (tmp, vis, sizeof (vis ));
// No effect on Dyeing
If (get_cnt (I) = 0) continue;
If (IDAstar (dep + 1) return true;
Memcpy (vis, tmp, sizeof (vis ));
}
Return false;
}
Int main ()
{
While (scanf ("% d", & n )! = EOF & n)
{
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
Scanf ("% d", & maze [I] [j]);
}
}
Mem (vis, 0 );
Floodfill (0, 0, maze [0] [0]);
Depth = get_h ();
While (true)
{
If (IDAstar (0) break;
Depth ++;
}
Printf ("% d \ n", depth );
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <map>
# Include <cstring>
# Include <cmath>
# Include <vector>
# Include <algorithm>
# Include <set>
# Include <string>
# Include <queue>
# Define inf 1 <30
# Define M 60005
# Define N 10005
# Define maxn300005
# Define eps 1e-10
# Define zero (a) fabs (a) <eps
# Define Min (a, B) (a) <(B )? (A) (B ))
# Define Max (a, B) (a)> (B )? (A) (B ))
# Define pb (a) push_back ()
# Define mem (a, B) memset (a, B, sizeof ())
# Define LL long
# Define lson step <1
# Define rson step <1 | 1
# Define MOD 1000000009.
Using namespace std;
Int maze [10] [10];
Int n;
Int way [4] [2] = {, 0,-, 0 };
Int vis [10] [10]; // ID of each node. If it is 1, it indicates that it is connected to the upper left. If it is 2, it indicates that it is not directly connected to the upper left but adjacent to the upper left connected block.
Bool check (int x, int y)
{
If (x <0 | y <0 | x> = n | y> = n) return false;
Return true;
}
Void floodfill (int x, int y, int c)
{
Vis [x] [y] = 1;
For (int I = 0; I <4; I ++)
{
Int tx = x + way [I] [0];
Int ty = y + way [I] [1];
If (! Check (tx, ty) continue;
If (vis [tx] [ty] = 1) continue;
If (maze [tx] [ty] = c) floodfill (tx, ty, c );
Else vis [tx] [ty] = 2;
}
}
// If col is dyed, how many grids will be added to the connected block?
Int get_cnt (int col)
{
Int cnt = 0;
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
If (maze [I] [j] = col & vis [I] [j] = 2)
{
Cnt ++;
Floodfill (I, j, maze [I] [j]);
}
}
}
Return cnt;
}
// Evaluate function, indicating the colors except the connected Blocks
// That is, the minimum number of dyeing times.
Int get_h ()
{
Bool flag [6]; mem (flag, false );
Int cnt = 0;
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
If (vis [I] [j]! = 1 &&! Flag [maze [I] [j])
{
Cnt ++;
Flag [maze [I] [j] = true;
}
}
}
Return cnt;
}
Int depth;
Bool IDAstar (int dep)
{
If (depth = dep) return get_h () = 0;
If (dep + get_h ()> depth) return false;
For (int I = 0; I <6; I ++)
{
Int tmp [10] [10];
Memcpy (tmp, vis, sizeof (vis ));
// No effect on Dyeing
If (get_cnt (I) = 0) continue;
If (IDAstar (dep + 1) return true;
Memcpy (vis, tmp, sizeof (vis ));
}
Return false;
}
Int main ()
{
While (scanf ("% d", & n )! = EOF & n)
{
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
Scanf ("% d", & maze [I] [j]);
}
}
Mem (vis, 0 );
Floodfill (0, 0, maze [0] [0]);
Depth = get_h ();
While (true)
{
If (IDAstar (0) break;
Depth ++;
}
Printf ("% d \ n", depth );
}
Return 0;
}