(백준) 모자이크 - 2539

2021. 7. 16. 12:26·알고리즘/백준

https://www.acmicpc.net/problem/2539

 

2539번: 모자이크

수찬이는 선생님을 도와서 교실 벽면을 장식할 모자이크 그림을 그리기로 하였다. 이를 위하여 직사각형 모양의 큰 도화지를 준비하여 교실 벽에 붙이고 1cm 간격으로 가로선과 세로선을 그려서

www.acmicpc.net

이분탐색 문제를 풀어보고 있는데 항상 이분탐색에서 부등호 처리가 헷갈려서 정리해본다

 

이분탐색에서 범위설정하는 경우를 나눠본다면

1) 원하는 값에 부합하는 경우가 유일한 경우

2) 원하는 값에 도달하더라도 가능한 값이 더 존재할 수 있어서 하한값을 높여가며 값에 해당하는 마지막 부분을 찾는 경우

 - 최대 이익

3) 원하는 값에 도달하더라도 가능한 값이 더 존재할 수 있어서 상한값을 낮춰가면서 값에 해당하는 첫 부분을 찾는 경우

- 최소 비용

 

2번과 3번은 lower_bound, upper_bound라는 용어가 존재하는데 c++에는 해당하는 라이브러리가 존재하지만 자바에는 없으므로 알아서 구현을 해줘야한다

 

이번 문제는 upper_bound로 이분탐색을 해야했던 문제였다


코드
public class 모자이크_2539 {
	static int r, c;
	static int page;
	static int N;
	static int Min;
	static ArrayList<Integer> columnList = new ArrayList<>(); // 구멍의 열을 담는 리스트
	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(br.readLine());
		r = Integer.parseInt(st.nextToken());
		c = Integer.parseInt(st.nextToken());

		page = Integer.parseInt(br.readLine().trim());
		N = Integer.parseInt(br.readLine().trim());

		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			int y = Integer.parseInt(st.nextToken());
			int x = Integer.parseInt(st.nextToken());
			Min = Math.max(Min, y); // 이분탐색을 위한 최소값 (높이의 최대값)
			columnList.add(x);
		}
		Collections.sort(columnList); // 이분탐색을 위한 정렬
		binarySearch();
	}

	private static void binarySearch() {
		int low = Min;
		int high = 1000000; // 최대 높이 백만
		int mid;

		while (low < high) {
			mid = (low + high) / 2;
            
			int pageCnt = matching(mid); // mid값이 색종이의 넓이, 이 값으로 구멍을 가려본다

			if (pageCnt > page) // 만약 사용된 종이 개수가 원하는 개수보다 많은 경우 길이를 늘린다
				low = mid + 1;
			else // 사용된 종이 개수가 적거나 같다면 색종이 길이를 더 줄여 본다 (upper bound)
				high = mid; // 해당 값을 상한값으로 두고 더 낮은 값으로 더 진행
		}
		System.out.println(low); // 최종 색종이의 길이
	}

	private static int matching(int size) {
		// 선택된 넓이의 색종이로 구멍들을 전부 채워본다
		int start = columnList.get(0);
		int pageCount = 0;

		int i = 0;
		loop:
		while (true) {
			while (columnList.get(i) < start + size) { //색종이 범위 내에 있는 구멍은 다 제거
				i++;
				if (i >= columnList.size()) { // 마지막 구멍까지 다 넣었으면 색종이 개수 더해주고 종료
					pageCount++;
					break loop;
				}
			}
			start = columnList.get(i); // 다음 구멍의 위치를 시작위치로 갱신
			pageCount++;
		}

		return pageCount;
	}
}

 

반응형
저작자표시 (새창열림)

'알고리즘 > 백준' 카테고리의 다른 글

(백준) 음악프로그램 - 2623  (0) 2021.07.23
(백준) 보스몬스터 전리품 - 20005  (0) 2021.07.22
(백준) 가운데서 만나기 - 21940  (0) 2021.07.22
(백준) 평범한 베낭 - 12865  (0) 2021.07.19
(백준) 다리만들기 - 2146  (2) 2021.07.16
'알고리즘/백준' 카테고리의 다른 글
  • (백준) 보스몬스터 전리품 - 20005
  • (백준) 가운데서 만나기 - 21940
  • (백준) 평범한 베낭 - 12865
  • (백준) 다리만들기 - 2146
구름뭉치
구름뭉치
구름의 개발일기장
  • 구름뭉치
    구름 개발일기장
    구름뭉치
  • 전체
    오늘
    어제
    • ALL (283)
      • 프로젝트 (23)
        • 토스페이먼츠 PG 연동 시리즈 (12)
        • JWT 방식 인증&인가 시리즈 (6)
        • 스우미 웹 애플리케이션 프로젝트 (1)
        • 스프링부트 기본 보일러 플레이트 구축 시리즈 (2)
        • 마이크로서비스 아키텍쳐 시리즈 (1)
      • 스프링 (43)
        • 스프링부트 API 설계 정리 (8)
        • 스프링부트 RestAPI 프로젝트 (18)
        • 스프링부트 WebSocket 적용기 (3)
        • 스프링 JPA 정리 시리즈 (5)
        • 스프링 MVC (5)
        • 스프링 배치 (2)
        • 토비의 스프링 정리 (2)
      • 기술 학습 (28)
        • 아파치 카프카 (9)
        • 클린 코드 (4)
        • 디자인 패턴의 아름다움 (2)
        • 모던 자바 인 액션 (7)
        • JVM 스레드 딥다이브 (6)
      • Web (25)
        • 정리글 (20)
        • GraphQL 정리글 (2)
        • Jenkins 정리글 (3)
      • 취업 (6)
      • CS (77)
        • 네트워크 전공 수업 정리 (11)
        • OSI 7계층 정리 (12)
        • 운영체제 정리 (19)
        • 데이터베이스 정리 (5)
        • MySql 정리 (17)
        • GoF의 Design Pattern 정리 (12)
      • 알고리즘 (70)
        • 백준 (56)
        • 프로그래머스 (12)
        • 알고리즘 정리본 (1)
      • 기초 지식 정리 (2)
      • 일상 (8)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    크로아티아
    마우스 패드
    키보드 손목 받침대
    mx master s3 for mac
    부다페스트
    레이저
    마우스
    류블라냐
    동유럽
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
구름뭉치
(백준) 모자이크 - 2539
상단으로

티스토리툴바