[java] sw expert academy - 홈 방범 서비스

2 분 소요

업데이트:

문제

SWEA - 홈 방범 서비스
마름모 모양의 방범서비스를 제공할 때 이익을 얻을 수 있는 위치 내 최대 집의 개수를 구하는 문제

풀이

마름모 모양을 어떻게 만드는지가 이 문제의 관건이라고 생각한다

for문 사용

나는 x, y가 마름모의 중심 좌표라고 할 때 2중 for문으로 마름모 영역을 구했다
간만에 펜잡고 계산하며 식을 세웠다..

way 1

x, y : 마름모의 중심 위치
k : 마름모의 크기

  • 소스코드(영역구하는 2중 for문)
    for (int i = x - k + 1; i < k + x; i++) {
          for (int j = y - (k - 1 - Math.abs(x - i)); j < y + 1 + (k - 1 - Math.abs(x - i)); j++) {
              if (isBoundary(i, j) && map[i][j]) {
                  val++;
              }
          }
      }
    

나는 수포자여서 이런 식을 계산하는 데엔 취약하다..

bfs 사용

way 2
다르게 생각하면 중심위치부터 인접한 4방향으로 한칸씩 확장한다
확장한 곳에서 또 4방향 확장한다 … 변수를 하나 둬서 k단계까지 확장한다고 생각하고
size만큼 bfs를 돌아도 같은 영역을 확인할 수 있다

고려해야 할 점은
맵의 크기가 10*10 이라고 할 때 전체 집이 포함되게 마름모를 그린다면??

소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution {
	static int N;
	private static int M;
	private static boolean[][] map;
	static int max = Integer.MIN_VALUE;
	static int cost;

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int TC = Integer.parseInt(br.readLine());
		for (int tc = 1; tc < TC + 1; tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			map = new boolean[N][N];
			max = 1;
			for (int i = 0; i < N; i++) {
				st = new StringTokenizer(br.readLine());
				for (int j = 0; j < N; j++) {
					map[i][j] = st.nextToken().equals("1") ? true : false;
				}
			}

			for (int k = 2; k < N + 3; k++) {
				cost = k * k + (k - 1) * (k - 1);
				for (int i = k / 2 - 1; i < N - k / 2+2; i++) {
					for (int j = k / 2 - 1; j < N - k / 2+2; j++) {
						chkCost(i, j, k);
					}
				}
			}
			System.out.println("#" + tc + " " + max);
		}
	}

	private static void chkCost(int x, int y, int k) {
		int val = 0;
		for (int i = x - k + 1; i < k + x; i++) {
			for (int j = y - (k - 1 - Math.abs(x - i)); j < y + 1 + (k - 1 - Math.abs(x - i)); j++) {
				if (isBoundary(i, j) && map[i][j])
					val++;
			}
		}
		if (val * M - cost >= 0)
			max = Math.max(max, val);

	}

	private static boolean isBoundary(int i, int j) {
		if (i > -1 && j > -1 && i < N && j < N)
			return true;
		return false;
	}
}

댓글남기기