백준 - 16207: 직사각형

2025. 3. 14. 15:42·Algorithm

문제링크

 

문제 설명

풀이 흐름

  • 각 막대별로 최대 1번씩만 기계를 사용할 수 있다는 것에 주목했습니다. 이는 길이의 차가 2이상인 막대는 직사각형의 평행한 변으로 만들 수 없다는 뜻입니다.
  • 주어진 막대의 길이들을 정렬한 이후에 최대값부터 순차적으로 탐색하면서 직사각형을 만들 수 있는 4개의 수를 찾았습니다.
    • 최대값부터 순차적으로 탐색하는 이유는 다음과 같습니다. (a, b, c, d인 실수가 있고, a >= b >= c >= d 라고 가정)
      • (a * b + c * d) - (a * d + b * c) = a * (b - d) - c * (b - d) = (a - c) * (b - d) >= 0
      • (a * b + c * d) - (a * c + b * d) = a * (b - c) - d * (b - c) = (a - d) * (b - c) >= 0
      • 따라서 (a * b) + (c * d)가 가장 큰 값이므로 {a, b}, {c, d}의 쌍으로 직사각형을 만들 때가 가장 넓이가 최대입니다.
    • 직사각형이 되기 위해선 마주보는 변의 길이가 같아야 됩니다. 그러므로 {a, a + (1 or 0), b, b + (1 or 0)}이 되는 조합을 찾아야 합니다. (tmp는 직사각형을 만들 막대의 길이, i는 tmp에 값을 넣을 인덱스라고 가정)
      • i가 양수라면 한 변의 길이를 정하기 전이라는 뜻이므로 현재 탐색 중인 값을 tmp[i]에 넣습니다.
      • i가 음수라면 현재 탐색 중인 값을 tmp[i - 1]과 비교합니다.
        • 만약 현재 탐색 중인 값이 tmp[i - 1]과 2 이상 차이나면 tmp[i - 1]에 현재 탐색 중인 값을 넣습니다.
        • 만약 현재 탐색 중인 값이 tmp[i - 1]과 1 이하로 차이나면 tmp[i]에 현재 탐색 중인 값을 넣고 i를 1 증가시킵니다.
        • 만약 i가 4가 되면 tmp에 있는 값들로 직사각형의 넓이를 구하고 ans에 더해준 뒤 i를 0으로 초기화 시키고 위 과정을 반복합니다.

코드

import java.util.*;
import java.io.*;

public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        int N = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        long[] arr = new long[N];
        for (int i = 0; i < N; i++) {
            arr[i] = Long.parseLong(st.nextToken());
        }
        Arrays.sort(arr);
        long ans = 0;
        long[] tmp = new long[4];
        int idx = 0;
        for (int i = N - 1; i >= 0; i--) {
            if (idx % 2 == 0) {
                tmp[idx] = arr[i];
                idx++;
            } else {
                if (tmp[idx - 1] - arr[i] <= 1) {
                    tmp[idx] = arr[i];
                    idx++;
                } else {
                    tmp[idx - 1] = arr[i];
                }
            }
            if (idx == 4) {
                ans += tmp[1] * tmp[3];
                idx = 0;
            }
        }

        bw.write(String.valueOf(ans));

        bw.flush();

        bw.close();
        br.close();
    }
}

'Algorithm' 카테고리의 다른 글

브루트포스 (완전 탐색) 알고리즘  (0) 2025.03.23
LeetCode - 2206. Divide Array Into Equal Pairs  (0) 2025.03.17
LeetCode - 1358. Number of Substrings Containing All Three Characters  (1) 2025.03.11
LeetCode - 3208. Alternating Groups II  (1) 2025.03.09
LeetCode - 1980. Find Unique Binary String  (1) 2025.02.20
'Algorithm' 카테고리의 다른 글
  • 브루트포스 (완전 탐색) 알고리즘
  • LeetCode - 2206. Divide Array Into Equal Pairs
  • LeetCode - 1358. Number of Substrings Containing All Three Characters
  • LeetCode - 3208. Alternating Groups II
ggio
ggio
개발 공부를 하며 배운 내용을 기록합니다.
  • ggio
    기록을 하자
    ggio
  • 전체
    오늘
    어제
    • 분류 전체보기 (41)
      • SW마에스트로 (5)
      • System Architecture (8)
      • Algorithm (15)
      • Side Tech Notes (7)
      • CS (5)
      • 취준 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    토스 NEXT
    프로액터 패턴
    비관락
    fail back
    알고리즘
    ha 아키텍처
    객체지향
    부트캠프
    leetcode
    시스템 설계
    코테
    Programming
    Algorithm
    멀티 코어
    소마
    분산락
    소프트웨어 마에스트로
    3PC
    메시지 큐
    지리적 분산
    리액터 패턴
    프로그래밍
    코딩테스트
    at-least-once
    시스템 아키텍쳐
    다중화
    SW마에스트로
    리트코드
    매일메일
    fail over
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
ggio
백준 - 16207: 직사각형
상단으로

티스토리툴바