[JAVA] SWEA 1979 어디에 단어가 들어갈 수 있을까
2022. 7. 7.
반응형

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PuPq6AaQDFAUq 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

1. 서론

 

D2 레벨이라서 풀이를 생각하고도 아니 근데 이렇게 복잡하게 푸는 게 맞다고? 생각했는데 복잡하게 푸는 게 맞았다... '충격'

 

2. 문제 풀이

 

N x N 배열이 주어진다. 특이한 점은 나는 1이 블록이고 0이 빈칸이라고 생각했는데 반대였다.

블록 부분을 제외한 곳에 길이가 m인 단어를 넣는다고 가정할 때 배열 안에 단어가 들어갈 수 있는 곳은 몇 군데 있는지를 구하는 문제이다.

 

풀이 과정은 조금 복잡한데 논리 자체는 간단했다.

 

1) 배열을 돌다가 빈칸을 발견하면 그 자리로부터 그림을 보니까 '=>' 이쪽 방향이랑 ⬇️ 이 방향으로 m의 길이만큼 비어있는지 확인한다.

 

2-1) m의 길이만큼 비어있으면 '=>' 이 방향이면 이 방향 기준 맨 첫 번째 배열 값의 왼쪽 칸이랑 맨 마지막 배열 값의 오른쪽 칸이 블록으로 막혀있는지 확인하고

2-2) ⬇️ 이 방향이면 마찬가지로 맨 첫 번째 배열 값의 위칸, 그리고 맨 마지막 배열 값의 아랫칸이 막혀있는지 체크한다.

 

3) 위의 조건들이 충족하면 카운트를 해준다.

 

3. 코드 설명

 

import java.util.*;

public class Solution {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
        
        int t = s.nextInt();
        
        for (int p = 0; p < t; p++) {
        	int n = s.nextInt(); int k = s.nextInt();
        	
        	int[][] a = new int[n][n];
        	
        	for (int i = 0; i < n; i++) 
        		for (int j = 0; j < n; j++) 
        			a[i][j] = s.nextInt();
        		
        	int[] dx = {0, 1}, dy = {1, 0};
        	
        	int cnt = 0;
        	
        	for (int i = 0; i < n; i++) {
        		for (int j = 0; j < n; j++) {
        			if (a[i][j] == 1) {
        			int q = 0, f = 0, x = i + dx[q], y = j + dy[q];
        			if (x >= 0 && x < n && y >= 0 && y < n && a[x][y] == 1) {
        				for (int w = 1; w < k; w++) {
        					x = i + dx[q] * w; y = j + dy[q] * w;	
        					if (x >= 0 && x < n && y >= 0 && y < n && a[x][y] == 1)
        						f++;
        					}
        					if (f == k - 1) {
        						int c1 = 0;
        						if (j == 0 || j == n - 1 || (j - 1 >= 0 && a[i][j - 1] == 0) || (j + 1 < n && a[i][j + 1] == 0) )
        							c1++;
        							
        						int c2 = 0;
        						if (y == 0 || y == n - 1 || (y - 1 >= 0 && a[x][y - 1] == 0) || (y + 1 < n && a[x][y + 1] == 0) )
        							c2++;
        								
        						if (c1 != 0 && c2 != 0)
        							cnt++;
        					}
        							
        				}
        			 q = 1; f = 0; x = i + dx[q]; y = j + dy[q];
        			 if (x >= 0 && x < n && y >= 0 && y < n && a[x][y] == 1) {
         				for (int w = 1; w < k; w++) {
         					x = i + dx[q] * w; y = j + dy[q] * w;
         					if (x >= 0 && x < n && y >= 0 && y < n && a[x][y] == 1)
         						f++;
         					}
         					if (f == k - 1) {
         						int c1 = 0;
         						if (i == 0||i == n - 1 || (i - 1 >= 0 && a[i - 1][j] == 0) || (i + 1 < n && a[i + 1][j] == 0))
         							c1++;
         							
         						int c2 = 0;
         						if (x == 0 || x == n - 1 || (x - 1 >= 0 && a[x - 1][y] == 0) || (x + 1 < n && a[x + 1][y] == 0))
         							c2++;
         								
         						if (c1 != 0 && c2 != 0)
         							cnt++;
         					}			
         				}
        			}				
        		}
        	}
        	System.out.println("#" + (p + 1) +  " " + cnt);
        }   
	}
}

 

꽤나 코드가 복잡^^ dx, dy 배열에서 오른쪽 방향으로 가는가, 아래쪽 방향으로 가는가를 위한 값을 넣어줬다.

그리고 위에서 말한 대로 1인 곳에서 한 칸 이동해 m의 길이만큼 갈 수 있는지를 f변수를 써서 카운트해줬다.

그리고 오른쪽으로 가냐, 아래쪽으로 가냐에 따라서 이동방향도 바뀌고 조건도 바뀌어서 비슷한 코드를 두 번 쓰다 보니까 코드가 무지 길어졌다. 나름 줄이고 줄인 게 이만큼... ㅠ

 

아니 이클립스에선 멀쩡한데 줄 맞춤 난리 나는 거 무슨 일이냐... 극혐 C++로 돌아가고 싶어

 

 

 

 

 

 

 

반응형
myoskin