题目
题解思路
法一
利用BFS倒推出所有状态 预处理 存表 ,查表搜答案。时间复杂度不好估计。
法二
利用二进制枚举第一行的所有状态,定下第一行,然后走第二行,此时能处理第一行没开的只有第二行。以此类推
最后检查最后一行的结果和按的次数。取出答案。
时间复杂度 2^5 * 5 * 5*n
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
char mp[10][10] ;
int f[10][10] ;
int dx[5] = { 0 , 0 , 1 , -1 , 0 };
int dy[5] = { 1 , -1 , 0 , 0 , 0 };
void sk( int xx ,int yy )
{
for (int i = 0 ; i < 5 ; i++ )
{
int fx = xx + dx[i] ;
int fy = yy + dy[i] ;
if ( fx >= 0 && fy >= 0 && fx < 5 && fy < 5 )
f[fx][fy] = ( f[fx][fy] + 1 )%2 ;
}
}
bool che (int l )
{
for (int i = 0 ; i < 5 ; i++ )
if ( f[l][i] == 0 )
return 0;
return 1;
}
int main ()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
while(n--)
{
int ans = INF ;
for (int i = 0 ; i < 5 ; i++ )
cin>>mp[i];
for ( int i = 0 ; i < 1 << 5 ; i++ )
{
int tmp = 0 ;
for (int i = 0 ; i < 5 ; i++ )
for (int j = 0 ; j < 5 ; j++ )
f[i][j] = mp[i][j] - '0' ;
for (int j = 0 ; j < 5 ; j++ )
{
if ( i >> j & 1 )
{
sk(0,j);
tmp++;
}
}
for (int j = 1 ; j < 5 ; j++ )
{
for (int k = 0 ; k < 5 ; k++ )
{
if ( f[j-1][k] == 0 )
{
sk(j,k);
tmp++;
}
}
}
if ( che(4) && tmp <= 6 )
ans = min( ans , tmp );
}
if ( ans != INF )
cout<<ans<<"\n";
else
cout<<"-1\n";
}
return 0 ;
}