-
Q. 20366 자바 : 같이 눈사람 만들래?코딩테스트/백준_Java 2023. 3. 27. 22:27
문제 :boj.kr/20366
골드 3 난이도의 문제이다.
투 포인터 강의를 듣고나서, 투 포인터 유형의 다른 문제들을 찾아보다가 발견한 문제이다.
처음에 문제를 봤을 때는 어떻게 접근해야 할 지 감이 안잡혔었는데,
감이 안잡혀서 검색을 했더니, 세 용액 문제와 비슷한, 네 용액 문제로 풀면 된다는 내용이 있길래
그 내용만 보고 추측해서 풀었더니 다행히 풀렸다.(다른 블로그 코드 참고x)
문제를 보면 하나의 눈사람은 두 개의 눈덩이로 구성되고 눈덩이가 주어지면,
두 눈사람의 키 차이가 가장 작은 값을 구하라는 문제이다.
1. 투 포인터 알고리즘을 이용해 값을 조정하려면,
눈덩이들이 정렬된 상태여야 하므로 먼저 정렬을 해준다. - O(N log N)
2. 네 개의 값을 뽑아야 하므로 먼저 두 개의 값을 선택하고- O(N^2)
이후에 다른 두 값을 투 포인터 알고리즘을 사용해 키 차이가 가장 작아지도록 구한다 - O(N)
(이 때 네개의 값이 모두 다른 눈덩이를 선택해야 하므로 같은 눈덩이일 경우를 생각해야 한다.)
3. 두 눈사람의 키 차이가 가장 작은 값 이므로 절댓값이 0에 가장 가까운 값이 이 문제에서 원하는 값이고,
위의 방식을 사용해서 정답을 계산한다.
그래서 내가 푼 코드의 시간 복잡도는 N logN + N^2 + N 이므로 약 O(N^2)의 시간복잡도를 가지고,
이 문제의 입력 조건을 확인하면 N의 최대값이 600이므로 시간초과가 나지 않을것을 예상할 수 있다.
주의해야 할 자료형은 눈덩이의 지름 H의 최대값이 10^9이므로 이 값들은 int 범위를 벗어나지 않고,
네 눈덩이의 합 역시 int 범위 내에서 처리가 가능하다. (세 용액 문제는 Long을 이용해야 했다)
import java.io.*; import java.util.*; public class Main { static FastReader scan = new FastReader(); static StringBuilder sb = new StringBuilder(); static int N, v1, v2, v3, v4; static int best_sum = Integer.MAX_VALUE; static int[] A; static void input() { N = scan.nextInt(); A = new int[N + 1]; for (int i = 1; i <= N; i++) { A[i] = scan.nextInt(); } } static void func(int idx1, int idx2) { int L = 1, R = N; int cur = A[idx1] + A[idx2]; while (L < R) { if (L == idx1 || L == idx2) { L++; continue; } if (R == idx1 || R == idx2) { R--; continue; } int sum = A[L] + A[R] - cur; if (Math.abs(sum) < best_sum){ best_sum = Math.abs(sum); } if (A[L] + A[R] > cur) R--; else L++; } } static void pro() { Arrays.sort(A, 1, N + 1); for (int i = 1; i < N; i++) { for (int j = i + 1; j <= N; j++) { func(i, j); } } System.out.println(best_sum); } public static void main(String[] args) { input(); pro(); } static class FastReader { // BufferedReader의 빠른 속도, // + Scanner의 타입별 입력값을 받는 기능을 혼합 // (자바 내부에 구현된 Scanner는 속도가 느림) // 다른분의 코드를 참고한 코드 BufferedReader br; StringTokenizer st; public FastReader() { br = new BufferedReader(new InputStreamReader(System.in)); } public FastReader(String s) throws FileNotFoundException { br = new BufferedReader(new FileReader(new File(s))); } String next() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } int nextInt() { return Integer.parseInt(next()); } long nextLong() { return Long.parseLong(next()); } double nextDouble() { return Double.parseDouble(next()); } String nextLine() { String str = ""; try { str = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return str; } } }
반응형'코딩테스트 > 백준_Java' 카테고리의 다른 글
Q. 2667 자바 : 단지번호붙이기 (0) 2023.03.29 Q. 1260 자바 : DFS와 BFS (0) 2023.03.28 Q.11559 자바 : Puyo Puyo(G4) (0) 2023.01.10 Q.16973 자바 : 직사각형 탈출(G4) (0) 2023.01.04 Q.7576 자바: 토마토(G5) (0) 2022.10.24