https://www.acmicpc.net/problem/1253
N개의 수 중에서 어떤 수가 다른 수 두 개의 합으로 나타낼 수 있다면 그 수를 “좋다(GOOD)”고 한다.
N개의 수가 주어지면 그 중에서 좋은 수의 개수는 몇 개인지 출력하라.
수의 위치가 다르면 값이 같아도 다른 수이다.
N이 2000 이하라, 으로 풀 수 있다. 다찾으면 이지만, 차이로 짝이되어 정답을 만드는 것이 가능한 숫자를 Set에 넣어, 뒤에서 발견하도록 했다. 정렬한 배열로 투포인터를 이용해으로 푸는 방법도 있는데, 다음번엔 이 방법으로 풀도록 연습하자.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Main {
    private static int countGoodCase(int n, int[] nums) {
        int answer = 0;
        for (int i = 0; i < n; i++)
            answer += (isGood(n, nums, i, nums[i])) ? 1 : 0;
        return answer;
    }
    // 한가지 케이스라도 찾았는지 여부
    private static boolean isGood(int n, int[] nums, int i, int target) {
        // 짝숫자를 빨리 찾기위한 Map
        Set<Integer> set = new HashSet<>();
        for (int j = 0; j < n; j++) {
            if (i == j) // 더할 두 숫자가 같은 수를 가르키는 경우 제외
                continue;
            // 지나간 수와 더해서 target 숫자를 만들 수 있는 숫자 발견, 알리고 중단
            if (set.contains(nums[j]))
                return true;
            // 못만드는 경우 해당 수와 짝이 되는 수를 수배목록에 추가
            else
                set.add(target - nums[j]);
        }
        return false;
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        int[] nums = new int[n];
        for (int i = 0; i < n; i++)
            nums[i] = Integer.parseInt(st.nextToken());
        br.close();
        System.out.println(countGoodCase(n, nums));
    }
}