转化为全零矩阵的最少反转次数

二进制矩阵,可以选择任意位置进行反转,其周围格子也会跟着反转
求使得矩阵全为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;
    }
};
posted @ 2023-05-27 02:41  失控D大白兔  阅读(13)  评论(0编辑  收藏  举报