当前位置: 首页 > news >正文

二进制矩阵全零转换问题 | DFS

问题描述

在一个古老的实验室里,两个研究员,小星和小月,获得了一个 m x n 的电路图,表示为二进制矩阵 grid。在这个矩阵中,他们可以对任意一个电路单元进行翻转操作。翻转操作会将所选单元的状态从 0 改为 1,或从 1 改为 0,同时影响与其相邻的上下左右单元。

小星和小月希望通过最少的翻转次数,将整个电路图变成全 0 的状态。如果这个目标无法实现,则返回 -1


测试样例

样例1:

输入:grid = [[0, 1], [1, 0]]
输出:2

样例2:

输入:grid = [[1, 0], [1, 1]]
输出:1

样例3:

输入:grid = [[0]]
输出:0

题解:

        很经典的一道题,原题叫棋盘覆盖问题,关键在于一个位置如果翻转两次等于没有翻转

        所以直接DFS遍历每个格子,每次都有翻和不翻两个情况,最后判断翻转次数即可。

        有一种更方便的方法,但是在时间上似乎不那么占优,先通过DFS生成随机1,0的长度为m*n的字符串,然后根据字符串的10,如果是1就翻转,如果是0就不翻,也不用每一位去异或,直接在对应位置+1代表翻转次数,最后遍历,如果是偶数就是0,奇数就是1即可。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<map>
#include<set>
using namespace std;
typedef long long int ll;

vector<vector<int>> grid1;
vector<vector<int>> vt;


int mincnt=100000;
int xt[5]={1,0,-1,0,0};
int yt[5]={0,1,0,-1,0};

int check(int x,int y){
    int n=vt.size();
    int m=vt[0].size();
    if(x>=0 && x<n && y>=0 && y<m){
        return 1;
    }
    return 0;
}

void f(int x,int y){
    for(int i=0;i<5;i++){
        int xx=x+xt[i];
        int yy=y+yt[i];
        if(check(xx,yy)){
            vt[xx][yy]++;
        }

    }
}

void col(string s){
    //cout << "YES" << "\n";
    //cout << s << "\n";

    int cnt=0;
    for(int i=0;i<vt.size();i++){
        for(int j=0;j<vt[i].size();j++){
            if(s[cnt]=='1'){
                //cout << "In" <<"\n";
                f(i,j);
            }
            cnt++;
        }
    }
    //cout << "pa1" <<"\n";
    /*
    for(int i=0;i<vt.size();i++){
        for(int j=0;j<vt[i].size();j++){
            cout << vt[i][j] << " ";
        }
        cout << "\n";
    }
    */
    bool is=true;
    for(int i=0;i<vt.size();i++){
        for(int j=0;j<vt[i].size();j++){
            if(vt[i][j]%2!=0){
                is=false;
                break;
            }
        }
    }
    //cout << "pa2" << "\n";
    if(is){
        int ct=0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='1'){
                ct++;
            }
        }
        if(ct<mincnt){
            mincnt=ct;
        }
    }
    //cout << "pa3" << "\n";
}

void dfs(string s,int num,int t){
    if(num==t){
        vt=grid1;
        col(s);
        return;
    }
    string a=s;
    a=a+'1';
    dfs(a,num+1,t);
    a=s;
    a=a+'0';
    dfs(a,num+1,t);
}

int solution(std::vector<std::vector<int>> grid) {
    vt=grid;
    grid1=grid;
    string s="";
    mincnt=100000;
    int x=grid.size();
    int y=grid[0].size();
    dfs(s,0,x*y);
    if(mincnt==100000){
        return -1;
    }
    return mincnt;
}

int main() {
    cout << (solution({{1, 0, 1}, {0, 1, 0}, {1, 0, 1}})) << endl;
    cout << (solution({{0, 1}, {1, 0}}) == 2) << endl;
    cout << (solution({{1, 0}, {1, 1}}) == 1) << endl;
    cout << (solution({{0, 0}, {0, 1}}) == 3) << endl;
    //cout << (solution({{0}}) == 0) << endl;
    return 0;
}

相关文章:

  • 建筑兔零基础Arduino自学记录47|安装和实战小灯闪烁-1
  • 91.HarmonyOS NEXT 应用国际化与本地化指南:打造全球化应用
  • 3.16学习总结 java
  • NumPy 函数用法详解:np.full 和 np.concatenate
  • MySQL数据库中的行锁
  • Qt MainWindow简单例子(文本编辑)
  • generallseteter插件生成内容和数据库不一致
  • 基于javaweb的SpringBoot博客商城管理系统设计与实现(源码+文档+部署讲解)
  • dart学习记录2
  • 基于STM32计时秒表设计Proteus仿真+程序+设计报告+原理图PCB+讲解视频
  • python中有几种作用域
  • 传输层自学
  • 配置单区域OSPF实验和报文抓包和分析
  • 51单片机的工作方式
  • 从模型到应用:大语言模型生态系统完全指南
  • 1.Windows+vscode+cline+MCP配置
  • HarmonyOS NEXT开发进阶(十三):网络请求封装
  • 目标:掌握无位置传感器(FOC)控制PMSM的设计与实现
  • 【go】Go 语言中 errors.Is 和 errors.As 的区别
  • RxSwift 学习笔记第三篇之RxSwift的Observer
  • 新开发银行如何开启第二个“金色十年”?
  • 中信银行一季度净利195.09亿增1.66%,不良率持平
  • 打工人的“小长假模式”,已经迫不及待地开启了
  • 新质观察|重塑低空经济的系统安全观
  • 赛力斯拟赴港上市:去年扭亏为盈净利59亿元,三年内实现百万销量目标
  • 全国电影工作会:聚焦扩大电影国际交流合作,提升全球影响力