-
[백준] #1080 행렬 - (BF)Algorithm/알고리즘 백준 풀이 2020. 2. 12. 17:24
문제
https://www.acmicpc.net/problem/1080
1080번: 행렬
첫째 줄에 행렬의 크기 N M이 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 행렬 A가 주어지고, 그 다음줄부터 N개의 줄에는 행렬 B가 주어진다.
www.acmicpc.net
목적
2개의 행렬 A, B가 주어졌을때 A를 변환하여 B로 만들때의 최소 변환횟수 구하기
+ 행렬의 변환은 변환위치를 기준으로 3*3만큼의 부분행렬을 변환함.
풀이
이 문제는 내가 제대로 이해를 못한거같다.
일단 변환은 3*3의 부분행렬만 변환하는것이므로 행렬의 원소를 오른쪽위에서 왼쪽아래로 하나하나 비교하면서 다르면 변환을 진행하되 범위에 제한을 N-3, M-3으로 줘야지 3*3행렬의 변환을 진행할수있다.
그리고 일단 오른쪽위부터 시작해서 내려오므로 가장 오른쪽위인 원소 즉, 기준점은 한번 변환된다면 다음에는 변환될 일이 없으므로 그리디하게 진행함.
코드
#include <iostream> using namespace std; int N, M; bool origin[51][51]; bool target[51][51]; //두개의 행렬을 같은지 비교함 bool isSame() { for (int i=0; i<N; ++i) { for (int j=0; j<M; ++j) { if (origin[i][j] != target[i][j]) return false; } } return true; } //기준점으로부터 3*3만큼의 부분행렬을 변환 void convert(int ip, int jp) { for (int i=ip; i<ip+3; ++i) { for (int j=jp; j<jp+3; ++j) { if (origin[i][j]) origin[i][j] = 0; else origin[i][j] = 1; } } } //기본 변환함수 //원소를 하나하나 오른쪽위에서부터 아래로 비교해나감 //변환후에는 같은지 확인 int change() { int cnt = 0; for (int i=0; i<N-2; ++i) { for (int j=0; j<M-2; ++j) { if (origin[i][j] != target[i][j]) { cnt++; convert(i, j); } if (isSame()) return cnt; } } return -1; } int main() { cin >> N >> M; for (int i=0; i<N; ++i) { for (int j=0; j<M; ++j) { scanf("%1d", &origin[i][j]); } } for (int i=0; i<N; ++i) { for (int j=0; j<M; ++j) { scanf("%1d", &target[i][j]); } } if (N<3 || M<3) { if (isSame()) { cout << 0; return 0; } cout << -1; return 0; } cout << change(); }
'Algorithm > 알고리즘 백준 풀이' 카테고리의 다른 글
[백준] #9252 LCS2(Longest Common Subsequence) - (DP) (0) 2020.03.02 [백준] #11659 구간합 구하기4 - (DP) (0) 2020.03.02 [백준] #2579 계단 오르기 - (DP) (0) 2020.03.02 [백준] #1932 정수삼각형 - (DP) (0) 2020.03.02 [백준] #1759 암호만들기 - (BF) (0) 2020.02.12