题目
给定一个N行M列的二维矩阵,矩阵中每个位置的数字取值为0或1。矩阵示例如: 1100 0001 0011 1111 现需要将矩阵中所有的1进行反转为0,规则如下: 1) 当点击一个1时,该1便被反转为0,同时相邻的上、下、左、右,以及左上、左下、右上、右下8 个方向的1(如果存在1)均会自动反转为0; 2)进一步地,一个位置上的1被反转为0时,与其相邻的8个方向的1(如果存在1)均会自动反转为0; 按照上述规则示例中的矩阵只最少需要点击2次后,所有值均为0。请问,给定一个矩阵,最少需要点击几次后,所有数字均为0?输入描述:
第一行为两个整数N和M,分别代表矩阵的行数和列数。
接下来的N行为矩阵的初始值,每行M个整数
输出描述:
输出一个整数,表示最少需要点击的次数
示例1:
输入:
3 3
1 0 1
0 1 0
1 0 1输出:
1
示例2:
输入:
4 4
1 1 0 0
0 0 0 1
0 0 1 1
1 1 1 1输出:
2
思路
1:dfs深度搜索
#include<bits/stdc++.h> using namespace std; int dir[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1}; // 8个方向 8*vector<2> void dfs(vector<vector<int>> &nums, int i, int j); int main() { int n,m; cin >> n >> m; vector<vector<int>> nums; for(int i = 0; i < n; i++) { vector<int> tmp; int temp; for(int j = 0; j < m; j++) { cin >> temp; tmp.push_back(temp); } nums.push_back(tmp); } //vector<vector<bool>> visit(n,vector<bool>(m,false)); int count = 0; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(nums[i][j]) { count++; dfs(nums, i, j); } } } cout << count << endl; return 0; } void dfs(vector<vector<int>> &nums, int i, int j) { nums[i][j] = 0; for(int k = 0; k < 8; k++) { int nextx = i+dir[k][0]; int nexty = j+dir[k][1]; if(nextx < 0 || nextx >= nums.size()) { continue; } if(nexty < 0 || nexty >= nums[0].size()) { continue; } if(nums[nextx][nexty] == 0) { continue; } dfs(nums, nextx, nexty); } }