|
| 1 | +/* |
| 2 | + * (14510) 나무 높이 |
| 3 | + * https://swexpertacademy.com/main/code/userProblem/userProblemSolver.do?contestProbId=AYFofW8qpXYDFAR4 |
| 4 | + */ |
| 5 | + |
| 6 | +import java.io.*; |
| 7 | +import java.util.*; |
| 8 | + |
| 9 | +/** |
| 10 | + * SW Expert Academy - 14510. 나무 높이 |
| 11 | + * @author YeJun, Jung |
| 12 | + * |
| 13 | + * @see #main(String[] args) |
| 14 | + * 1. 테스트케이스를 입력받는다. |
| 15 | + * 2. 솔루션을 실행한다. |
| 16 | + * |
| 17 | + * @see #input() |
| 18 | + * 3. 나무의 개수와 나무의 높이를 입력받는다. |
| 19 | + * |
| 20 | + * @see #solve() |
| 21 | + * 4. 입력받은 나무의 높이들 중에서 최대값을 찾는다. |
| 22 | + * 5. 홀수날, 짝수날이 각각 몇개 필요한지 저장할 변수를 선언한다. |
| 23 | + * 6. 각 나무 높이에 대해서... |
| 24 | + * 6-1. 나무가 얼마나 성장해야 하는지 계산한다. |
| 25 | + * 6-2. 가능한 짝수날에서 나무를 최대한 성장시키고, |
| 26 | + * 남은 높이는 홀수날에 성장시킨다. |
| 27 | + * 7. 각 나무 높이에 대해서 합산된 홀수날, 짝수날을... |
| 28 | + * 7-1. 짝수날을 홀수날 2개로 쪼개어 홀,짝,홀,짝 빈틈없이 채운다. |
| 29 | + * 8. 홀수날이 짝수날 보다 많다면 -> 첫번째 날(홀수) 1과 그외 홀수날들에 x2한 값을 더한다. |
| 30 | + * 짝수날이 홀수날 보다 많다면 -> 짝수날에 x2 한다. |
| 31 | + * 홀수날과 짝수날이 같다면 -> 홀수날의 합과 짝수날의 합을 더해준다. |
| 32 | + * |
| 33 | + * @see #print() |
| 34 | + * 9. bestDays를 화면에 출력한다. |
| 35 | + */ |
| 36 | +public class Solution { |
| 37 | + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); |
| 38 | + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); |
| 39 | + static StringTokenizer input; |
| 40 | + |
| 41 | + // ---------------------------------------------------------- |
| 42 | + |
| 43 | + public static void main(String[] args) throws IOException { |
| 44 | + // 1. 테스트케이스를 입력받는다. |
| 45 | + final int testCount = Integer.parseInt(reader.readLine().trim()); |
| 46 | + |
| 47 | + for (int testCase = 1; testCase <= testCount; testCase++) { |
| 48 | + // 2. 솔루션을 실행한다. |
| 49 | + new Solution(testCase).run(); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + // ---------------------------------------------------------- |
| 54 | + |
| 55 | + int testCase; |
| 56 | + int bestDays; |
| 57 | + |
| 58 | + int treeLen; |
| 59 | + int[] treeArr; |
| 60 | + |
| 61 | + public Solution(int testCase) { |
| 62 | + this.testCase = testCase; |
| 63 | + } |
| 64 | + |
| 65 | + public void run() throws IOException { |
| 66 | + input(); |
| 67 | + solve(); |
| 68 | + print(); |
| 69 | + } |
| 70 | + |
| 71 | + public void input() throws IOException { |
| 72 | + // 3. 나무의 개수와 나무의 높이를 입력받는다. |
| 73 | + |
| 74 | + treeLen = Integer.parseInt(reader.readLine().trim()); |
| 75 | + treeArr = new int[treeLen]; |
| 76 | + |
| 77 | + getLine(); |
| 78 | + for (int index = 0; index < treeLen; index++) { |
| 79 | + treeArr[index] = Integer.parseInt(input.nextToken()); |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + public void solve() { |
| 84 | + // 4. 입력받은 나무의 높이들 중에서 최대값을 찾는다. |
| 85 | + int maxH = 0; |
| 86 | + for (int h : treeArr) maxH = Math.max(maxH, h); |
| 87 | + |
| 88 | + // 5. 홀수날, 짝수날이 각각 몇개 필요한지 저장할 변수를 선언한다. |
| 89 | + int odd = 0, even = 0; |
| 90 | + |
| 91 | + // 6. 각 나무 높이에 대해서... |
| 92 | + for (int i = 0; i < treeLen; i++) { |
| 93 | + // 6-1. 나무가 얼마나 성장해야 하는지 계산한다. |
| 94 | + int diff = maxH - treeArr[i]; |
| 95 | + |
| 96 | + // 최대높이인 나무는 제외 |
| 97 | + if (diff == 0) continue; |
| 98 | + |
| 99 | + // 6-2. 가능한 짝수날에서 나무를 최대한 성장시키고, |
| 100 | + // 남은 높이는 홀수날에 성장시킨다. |
| 101 | + even += diff / 2; |
| 102 | + odd += diff % 2; |
| 103 | + } |
| 104 | + |
| 105 | + if (even > odd) { |
| 106 | + // 7. 각 나무 높이에 대해서 합산된 홀수날, 짝수날을... |
| 107 | + while (Math.abs(even - odd) > 1) { |
| 108 | + // 7-1. 짝수날을 홀수날 2개로 쪼개어 홀,짝,홀,짝 빈틈없이 채운다. |
| 109 | + even--; |
| 110 | + odd += 2; |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + // 8. 홀수날이 짝수날 보다 많다면 -> 첫번째 날(홀수) 1과 그외 홀수날들에 x2한 값을 더한다. |
| 115 | + // 짝수날이 홀수날 보다 많다면 -> 짝수날에 x2 한다. |
| 116 | + // 홀수날과 짝수날이 같다면 -> 홀수날의 합과 짝수날의 합을 더해준다. |
| 117 | + if (odd > even) { |
| 118 | + bestDays = odd * 2 - 1; |
| 119 | + } else if (even > odd) { |
| 120 | + bestDays = even * 2; |
| 121 | + } else { |
| 122 | + bestDays = odd + even; |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + public void print() throws IOException { |
| 127 | + // 9. bestDays를 화면에 출력한다. |
| 128 | + writer.write("#" + testCase); |
| 129 | + writer.write(" " + bestDays); |
| 130 | + writer.write("\n"); |
| 131 | + writer.flush(); |
| 132 | + } |
| 133 | + |
| 134 | + // ---------------------------------------------------------- |
| 135 | + |
| 136 | + private void getLine() throws IOException { |
| 137 | + input = new StringTokenizer(reader.readLine().trim()); |
| 138 | + } |
| 139 | +} |
0 commit comments