1. 문제
2470번: 두 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00
www.acmicpc.net
2. 접근방법
합이 0에 가깝게 만드는 두 수를 찾는 문제
합을 0에 가깝게 어떻게 만들까?
여기서 생각해보면
배열 안의 값중 합이 0에 가장 가깝게 만드는 경우는
두 수가 절대값으로 정렬했을 때 붙어있어야만 가능하다.
위 예제에서도 절대 값 정렬을 하면
-99 98 4 -2 -1
정답은 합이 -1인 -99와 98
뭔가 반례가 있지 않을까 싶어
다양한 경우를 생각해봤지만 반례를 찾지 못해
이대로 풀이를 해보니 맞았습니다를 받았다.
증명은 어떻게 해야할지 감이 잘안와서
지나가는 수학과님이 보신다면 증명 좀 해주면 감사하겠슴니다.
어쨌든 절대값으로 정렬하고
정렬된 배열에서 앞뒤 숫자 합을 구해
최소값이 나오게 하는 두 수를 구하면 된다.
3. 자바 코드
package Gold;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
public class G1_2470두용액 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
Integer [] arr = new Integer [N];
for(int i = 0 ; i < N ; i++)
arr[i] = Integer.parseInt(st.nextToken());
Arrays.parallelSort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Math.abs(o1)-Math.abs(o2);
}
});
int min = Integer.MAX_VALUE;
int x = 0;
int y = 0;
for(int i = 0 ; i < N-1; i++) {
if(Math.abs(Integer.sum(arr[i], arr[i+1])) < min) {
x = arr[i];
y = arr[i+1];
min = Math.abs(x+y);
}
}
if(x > y)
x = y ^ x ^(y=x);
System.out.println(x+" "+y);
}
}
4. 마치며
뭔가 반례가 있을 것 같은데 안나와서 더 당황..
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 4659 비밀번호 발음하기 (1) | 2021.06.13 |
---|---|
[백준] 15658 연산자 끼워넣기 (2) (2) | 2021.05.25 |
[백준] 17090 미로 탈출하기 (4) | 2021.04.12 |
[백준] 1946 신입사원 (1) | 2021.04.08 |
[백준] 1748 수 이어 쓰기1 (0) | 2021.03.15 |