https://www.acmicpc.net/problem/1744
1744번: 수 묶기
길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에
www.acmicpc.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static int n;
public static long cnt = 0;
public static int[] arr;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
arr = new int[n];
StringTokenizer st;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
// 1은 곱해주는것보다 더해주는게 이득
// 음수만 (앞에서부터)
// 0포함
int left = 0;
int right = n - 1;
cnt = 0;
for (; left < right; left += 2) {//등호 붙이면 안됨, 인덱스 bound 넘어감
if (arr[left] < 1 && arr[left + 1] < 1) {
cnt += arr[left] * arr[left + 1];
} else {
break;
}
}
// 양수만 (뒤에서부터)
// 양수는 1보다 큰애만
for (; right > 0; right -= 2) {
if (arr[right] > 1 && arr[right - 1] > 1) {
cnt += arr[right] * arr[right - 1];
} else {
break;
}
}
for (; right >= left; right--) {
cnt += arr[right];
}
System.out.println(cnt);
}
}
|
cs |
문제를 풀면서 중요한 부분
최대 값이 나오기 위해서는 수를 묶을 때
(1보다 양수 *1보다 양수)
(0*음수)
(음수*음수) 여야 한다.
1의 경우 1과 양수를 곱해주는것보다 1과 양수를 더해주는게 더 크다. 음수는 굳이 말할 필요도 없다.
이렇게 조건 분기를 해주고, 수를 정렬하면 앞에는 음수또는 양수들 중 작은 수 뒤에는 양수들이 자리할 것 이다.
그러면 앞에 있는 수부터 탐색해주는(사실상 음수를 묶어주기 위함) for문은
헛발질
1) 문제를 풀면서 크게 잘못 생각한게 있었는데 두개씩 묶는다는 것을 두개씩 묶는걸 두번만 가능하다고 이해한거였다. 나도 내가 왜 이렇게 이해한지 모르겠다 ㅋㅋㅋ 그래서 스스로 문제를 더 어렵게 만들고 있었다.
두개씩 묶기만 하면 그 개수는 제한이 없다...!
2) 이건 내가 처음에 작성한 코드인데 질문에 있는 반례를 넣어봐도 대부분 맞았다. 어디서 틀린지 모르겠어서 나중에 찾으면 다시 확인하려고 첨부해둔다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static int n;
public static long cnt = 0;
public static int[] arr;
public static long tie() {
cnt = 0;
int i = 0;
while (i < n) {
if (i < n - 1) {
if (arr[i] > 1 && arr[i + 1] > 1) {
cnt += arr[i] * arr[i + 1];
i += 2;
continue;
} else if (arr[i] <= 0 && arr[i + 1] <= 0) {
cnt += arr[i] * arr[i + 1];
i += 2;
continue;
}
}
if (i < n) {
cnt += arr[i];
i++;
}
}
return cnt;
}
public static long reverseTie() {
cnt = 0;
int i = n - 1;
while (i >= 0) {
if (i >= 1) {
if (arr[i] > 1 && arr[i - 1] > 1) {
cnt += arr[i] * arr[i - 1];
i -= 2;
continue;
} else if (arr[i] <= 0 && arr[i - 1] <= 0) {
cnt += arr[i] * arr[i - 1];
i -= 2;
continue;
}
}
if (i >= 0) {
cnt += arr[i];
i--;
}
}
return cnt;
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
arr = new int[n];
StringTokenizer st;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
// 스스로 엄청 어려운 조건을 넣고 있었음
// 묶는건 횟수 제한 없음 --> 난 두번인줄 알았
if (n == 1) {
System.out.println(arr[0]);
} else {
long ans = tie();
long ans2 = reverseTie();
if (ans >= ans2) {
System.out.println(ans);
} else {
System.out.println(ans2);
}
}
}
}
|
cs |
참고사이트
for문을 돌려서 음수*음수 1보다 큰 양수*1보다 큰 양수 끼리 하는 방법은 다른 사람의 코드를 참고했다.
https://mygumi.tistory.com/220
백준 1744번 수 묶기 :: 마이구미
이 글은 백준 알고리즘 문제 1744번 "수 묶기" 를 풀이한다. 문제의 접근 방법은 그리디 알고리즘으로써, 어떠한 자료구조를 요구하지는 않는다. 하지만 정답 비율이 낮은 문제로써, 까다로울 수
mygumi.tistory.com
'알고리즘 > 그리디' 카테고리의 다른 글
[C 백준] 실버 4/ 13305번 주유소 (0) | 2022.03.11 |
---|---|
[java 백준] 실버 2/ 1541번 잃어버린 괄호 (0) | 2022.02.15 |
[java 백준] 실버 2/1931번 회의실 배정 (0) | 2022.02.08 |
[java 백준] 실버 4/ 1783번 병든 나이트 (0) | 2022.02.06 |
[java 백준] 실버 5/ 10610번 30 (0) | 2021.11.04 |
댓글