2022-05-22
https://www.acmicpc.net/problem/1080
1080번: 행렬
첫째 줄에 행렬의 크기 N M이 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 행렬 A가 주어지고, 그 다음줄부터 N개의 줄에는 행렬 B가 주어진다.
www.acmicpc.net
실버 1의 문제이다. 문제는 굉장히 단순한데에 비해 난이도는 좀 높았던 것 같다. 행렬 뒤집는거를 어떻게 할지 고민하다가 지쳐서 답안 코드를 보고서야 해결했다 ㅠㅠ.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n,m;
int mata[51][51];
int matb[51][51];
void matrixChange(int x,int y){
for(int i=x;i<=x+2;i++){
for(int j=y;j<=y+2;j++){
mata[i][j]=1-mata[i][j];
}
}
}
int main()
{
freopen("input.txt","r",stdin);
cin>>n>>m;
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%1d",&mata[i][j]);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%1d",&matb[i][j]);
}
}
for(int i=0;i<=n-3;i++){
for(int j=0;j<=m-3;j++){
if(mata[i][j]!=matb[i][j]){
matrixChange(i,j);
cnt++;
}
}
}
bool flag=false;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(mata[i][j]!=matb[i][j]){
cnt=-1;
flag=true;
break;
}
}
if(flag==true)
break;
}
cout<<cnt;
}
일단 빈칸없이 주어지는 입력을 하나씩 받기 위해 필요한 scanf("%1d",&~~) 는 꼭 외워둬야 할 것 같다. 물론 문자열로 입력 받은다음에 아스키코드를 이용해서 숫자로 바꿀 수는 있지만 이 방법이 훨씬 간단하고 좋은 것 같다.
행렬은 3*3의 크기 단위로만 뒤집을 수 있으므로, 먼저 3*3이 언제까지 되는지를 알아야했다. 생각해보니 행은 N-3까지, 열은 M-3 까지 가능했다.
이중 for문을 돌리면서 a와 b가 다른점이 있다면 3*3크기만큼 뒤집어 주었다. 이 과정을 (0,0) 부터 (N-3,M-3) 까지 반복 했다. 이렇게 다 뒤집고 난 뒤에 만들어진 a와 b를 비교해서 모든점이 같다면 cnt변수를 출력해주었고, 하나라도 다른점이 있다면 a에서 b로 바뀔수 없다는 것이기 때문에 -1을 cnt에 대입해주고 break 를 해주었다.
항상 해결하고나면 그렇게까지 어렵지 않은거 같은데 풀기전에는 너무 어렵게 느껴진다 ㅠ.
'BOJ 문제풀이' 카테고리의 다른 글
#2225 합분해 (0) | 2022.05.22 |
---|---|
#9465 스티커 (0) | 2022.05.22 |
#2012 등수 매기기 (0) | 2022.05.21 |
#1789 수들의 합 (0) | 2022.05.21 |
#18310 안테나 (0) | 2022.05.21 |