[코딩테스트C++] 행렬

후이재·2020년 10월 17일
1

오늘의 문제

행렬

문제 접근

  • 입력의 크기가 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);
}

배울 점

  • 뒤집는걸 함수로 안하고 한줄로 수행했다. 정말 숏코딩을 향한 노력 용하다.
profile
공부를 위한 벨로그

0개의 댓글