오늘의 문제
행렬
문제 접근
- 입력의 크기가 50 * 50 = 250 밖에 안되는데 2초나 준다. 다 비교해봐도 된다는 뜻
- 두개의 행렬을 비교하여 다른 부분을 1로 체크한다.
- 1이 발생한곳을 기점으로 3*3 뒤집어본다.
- 왼쪽 위에서 오른쪽 아래까지 1인 경우 3*3부분을 flip한다.
- 모두 flip한 후에 1이 남아있는지 체크한다. 남아있으면 -1, 없으면 뒤집은 횟수 출력
나의 풀이
#include <iostream>
using namespace std;
int n, m;
const int MAX = 50;
int arr[MAX][MAX];
// 행렬
int flip(int a, int b){
for(int i=0;i<3;i++){
for(int j = 0; j<3;j++){
if(arr[a+i][b+j] == 0) arr[a+i][b+j] = 1;
else arr[a+i][b+j] = 0;
}
}
return 0;
}
int solution(){
int answer = 0;
for(int i=0;i<n-2;i++){
for(int j=0;j<m-2;j++){
if(arr[i][j] == 1 ){
answer++;
flip(i, j);
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(arr[i][j] == 1)
return -1;
}
}
return answer;
}
다른 풀이
#include<cstdio>
int n,m,d[50][50],i,j,t,x,y;
char a;
int main(){
scanf("%d %d",&n,&m);
for(i=0;i<n;i++){
for(j=0;j<m;j++){
scanf(" %c",&a);
d[i][j]=a-'0';
}
}
for(i=0;i<n;i++){
for(j=0;j<m;j++){
scanf(" %c",&a);
d[i][j] ^=(a-'0');
}
}
t=0;
for(i=0;i<n-2;i++){
for(j=0;j<m-2;j++){
if(d[i][j]){
t++;
for(x=0;x<3;x++)for(y=0;y<3;y++)d[i+x][j+y]=!d[i+x][j+y];
}
}
}
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(d[i][j]){
printf("-1");
return 0;
}
}
}
printf("%d",t);
}
배울 점
- 뒤집는걸 함수로 안하고 한줄로 수행했다. 정말 숏코딩을 향한 노력 용하다.