转化为全零矩阵的最少反转次数
二进制矩阵,可以选择任意位置进行反转,其周围格子也会跟着反转
求使得矩阵全为0的最少反转次数
1. 广度优先搜索
将每个状态转化为字符串进行存储,方便剪枝和压缩
class Solution {
public:
int m; int n;
vector<vector<int>> dir = {{0,0},{1,0},{0,1},{0,-1},{-1,0}};
int minFlips(vector<vector<int>>& mat) {
m = mat.size(); n = mat[0].size();
string str = vec_str(mat);
set<string> s; //剪枝
queue<string> q; //状态队列
s.insert(str);
q.push(str);
int count = 0;
while(!q.empty()){//最小
int len = q.size();
for(int times=0;times<len;times++){
string cur = q.front(); q.pop();
if(check(cur)) return count;//满足条件直接返回操作次数
for(int i=0;i<m;i++) //对所有位置进行翻转
for(int j=0;j<n;j++){
string next = transform(cur,i,j);
if(s.count(next)) continue;
q.push(next);
s.insert(next);
}
}
count++;
}
return -1;
}
bool check(string& s){
for(int i=0;i<s.size();i++)
if(s[i]=='1') return false;
return true;
}
string vec_str(vector<vector<int>>& mat){
string res;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
res.push_back(mat[i][j]+'0');
return res;
}
string transform(string s,int x,int y){
for(int i=0;i<dir.size();i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx<0||nx==m||ny<0||ny==n) continue;
s[nx*n+ny] = !(s[nx*n+ny]-'0')+'0';
}
return s;
}
};