m x n 이진 행렬 매트가 있다고 가정합니다. 한 단계에서 우리는 하나의 셀을 선택하고 해당 비트와 4개의 이웃이 있는 경우 모두 뒤집을 수 있습니다. mat를 0행렬로 변환하는 데 필요한 최소 단계 수를 찾아야 합니다. 솔루션이 없으면 -1을 반환합니다.
따라서 주어진 입력이 [[0,0], [0,1]]과 같으면 변경은 -
와 같습니다.
따라서 3단계가 필요하며 출력은 3이 됩니다.
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
- n :=행 수, m :=열 수, x :=0
- 초기화 i의 경우:=0, i
- j 초기화의 경우:=0, j
- j 초기화의 경우:=0, j
- x :=x + 왼쪽 시프트 매트[i][j] 값 (i * m) + j) 횟수
- j 초기화의 경우:=0, j
- dp[현재]를 반환
- ni :=i + dir[k][0]
- nj :=j + dir[k][1]
- ni <0 또는 nj <0 또는 ni>=n 또는 nj>=m이면 −
- 다음 부분은 무시하고 다음 반복으로 건너뜁니다.
- temp :=임시 XOR 2^ (ni * m) + nj)
- dp[temp] :=dp[현재] + 1
- q에 온도 삽입
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예시
#include <bits/stdc++.h> using namespace std; int dir[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}}; class Solution { public: int minFlips(vector<vector<int>>& mat) { int n = mat.size(); int m = mat[0].size(); int x = 0; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ x += (mat[i][j] << ((i * m) + j)); } } vector < int > dp(1 << (n*m), -1); dp[x] = 0; queue <int> q; q.push(x); while(!q.empty()){ int current = q.front(); q.pop(); if(current == 0)return dp[current]; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ int temp = current; temp ^= (1 << ((i *m) + j)); for(int k = 0; k < 4; k++){ int ni = i + dir[k][0]; int nj = j + dir[k][1]; if(ni < 0 || nj < 0 || ni >= n || nj >= m)continue; temp ^= (1 << ((ni *m) + nj)); } if(dp[temp] == -1){ dp[temp] = dp[current] + 1; q.push(temp); } } } } return -1; } }; main(){ Solution ob; vector<vector<int>> v = {{0,0},{0,1}}; cout << (ob.minFlips(v)); }
입력
{{0,0},{0,1}}
출력
3