题意:给定一个4*4的棋盘。棋盘上每个格子有黑白两种状态。每修改一个格子的状态,那么它上下左右的格子也随之被修改。目标是让所有格子都变成黑或者所有格子都变成白。问至少需要修改几次才能实现目标。
题解:给出了DFS,BFS两种解法。
DFS:
#include <iostream>
using namespace std;
int MIN;
bool cell[16];
bool success()
{
for ( int i = 0; i < 16; i++ )
if ( cell[i] != cell[0] )
return false;
return true;
}
void flip ( int n )
{
if ( n % 4 != 0 )
cell [n-1] = !cell[n-1];
if ( n % 4 != 3 )
cell [n+1] = !cell[n+1];
if ( n <= 11 )
cell [n+4] = !cell[n+4];
if ( n >= 4 )
cell [n-4] = !cell[n-4];
cell[n] = !cell[n];
}
void dfs ( int Nth_cell, int step )
{
bool check = success ();
if ( check || Nth_cell >= 16 )
{
if ( check && step < MIN )
MIN = step;
return;
}
flip ( Nth_cell );
dfs ( Nth_cell + 1, step + 1 );
flip ( Nth_cell );
dfs ( Nth_cell + 1, step );
}
int main()
{
char ch;
memset(cell,0,sizeof(cell));
for ( int i = 0; i < 16; i++ )
{
cin >> ch;
if ( ch == 'b' )
cell[i] = 1;
}
MIN = 17; // 最小步骤只要先设定大于16步即可。因为最多值需翻16次(每个格子翻一次,翻了两次等于没翻,翻了三次等于一次···)
dfs ( 0, 0 );
if ( MIN == 17 )
cout << "Impossible" << endl;
else
cout << MIN << endl;
return 0;
}
BFS:
#include <queue>
#include <iostream>
using namespace std;
#define Black 65535
#define White 0
int state [65536];
int filp ( int state_id, int position )
{
state_id ^= ( 1 << position );
if ( position >= 4 )
state_id ^= ( 1 << ( position-4 ) );
if ( position <= 11 )
state_id ^= ( 1 << ( position+4 ) );
if ( position % 4 > 0 )
state_id ^= ( 1 << ( position-1 ) );
if ( position % 4 < 3 )
state_id ^= ( 1 << ( position+1 ) );
return state_id;
}
int main()
{
char ch;
int current = 0;
queue<int> search;
memset( state, -1, sizeof(state) );
for ( int i = 0; i < 16; i++ )
{
cin >> ch;
if ( ch == 'b' )
current += ( 1 << i );
}
if ( current == Black || current == White )
{
cout << 0 << endl;
return 0;
}
state[current] = 0;
search.push ( current );
int next;
while ( ! search.empty () )
{
current = search.front ();
search.pop ();
for ( int i = 0; i < 16; i++ )
{
next = filp ( current, i );
if ( next == Black || next == White )
{
cout << state[current] + 1 << endl;
return 0;
}
if ( state[next] == -1 )
{
search.push ( next );
state[next] = state[current]+1;
}
}
}
cout << "Impossible" << endl;
return 0;
}