https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PuPq6AaQDFAUq
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++로 돌아가고 싶어
'Algorithm' 카테고리의 다른 글
[JAVA] SWEA 1961 숫자 배열 회전 (0) | 2022.07.09 |
---|---|
[JAVA] SWEA 2001 파리 퇴치 (0) | 2022.07.09 |
[JAVA] SWEA 1959 두 개의 숫자열 (0) | 2022.07.05 |
[C++] 프로그래머스 소수 찾기 (0) | 2022.06.18 |
[C++] 프로그래머스 전화번호 목록 (0) | 2022.06.17 |