[백준][Java]좋다 - 1253

·2025년 10월 13일
0

코딩테스트

목록 보기
15/16

[Gold IV] 좋다 - 1253

문제 링크

문제 설명

N개의 수 중에서 어떤 수가 다른 수 두 개의 합으로 나타낼 수 있다면 그 수를 “좋다(GOOD)”고 한다.

N개의 수가 주어지면 그 중에서 좋은 수의 개수는 몇 개인지 출력하라.

수의 위치가 다르면 값이 같아도 다른 수이다.

입력

첫째 줄에는 수의 개수 N(1 ≤ N ≤ 2,000), 두 번째 줄에는 i번째 수를 나타내는 Ai가 N개 주어진다. (|Ai| ≤ 1,000,000,000, Ai는 정수)

출력

좋은 수의 개수를 첫 번째 줄에 출력한다.

예제


나의 문제 풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        //N : 수의 개수
        int N = Integer.parseInt(br.readLine());
        int count = 0;

        StringTokenizer st = new StringTokenizer(br.readLine());

        long[] arr = new long[N];
        for (int i = 0; i < N; i++) {
            arr[i]= Long.parseLong(st.nextToken());
        }
        //배열 정렬
        Arrays.sort(arr);

        for(int k=0; k<N; k++){
            long find = arr[k];   //찾고자하는값
            int start = 0;
            int end = N-1;
            while (start < end){
                //합이 같으면
                if(arr[start] + arr[end] == find){
                    //find가 서로 다른 두 수의 합인지 체크 -> find가 5이고, start 0, end가 5일때와 같은 예외처리
                     if(start != k && end != k){
                         count ++;
                         break;
                     }else if(start==k){    //포인터중 하나가 타깃 k를 가리키면 그 포인터를 한칸 움직인다.
                        start ++;
                     }else if(end == k){
                         end --;
                     }
                //더한 값이 find보다 작으면 더 큰값을 만들기 위해 start++
                }else if(arr[start] + arr[end] < find){
                    start++;
                //더한 값이 find보다 크면 더 작은값을 만들기 위해 end--    
                }else{
                    end--;
                }
            }
        }
        System.out.println(count);
    }
}
  • N개의 수 중에서 어떤 수가 다른 수 두 개의 합을 나타내는 갯수를 찾는것이다.
  • 이것도 정렬 + 투포인트 알고리즘을 사용한다.
  • 단, 정렬된 데이터에서 자기자신을 좋은 수 만들기에 포함하면 안되므로 예외처리해줘야한다!

문제 풀어보기

1. 수를 입력받아 배열 A에 저장한 후 정렬한다.

2. 투 포인터 i,j를 배열 A의 양쪽 끝에 위치시키고, 투 포인터 이동 원칙을 활용해 탐색을 수행한다.(판별의 대상이 되는 수는 K라 한다.)

(1) A[i]+A[j] == find(찾고자 하는 값)이면

  • 서로 다른 두수의 값인지 체크 후 서로 다른 값이면 count++후 탐색 종료
  • 탐색 종료를 하는 이유는 좋은수가 되는 순서쌍의 개수를 찾는 것이 아니라, 좋은 수의 "개수"를 세는것이기 때문에 k가 이미 좋은 수라고 판명났기 때문에 탐색종료 하는것!
  • 만약 find와 값은 같지만 i가 타깃 인덱스 k와 같으면 i++, j와 타깃 인덱스 k가 같으면 j--

(2) A[i]+A[j] < find 이면

  • 더 큰값을 만들기 위해 i++

(3) A[i]+A[j] > find 이면

  • 더 작은 값을 만들기 위해 j--
profile
배우고 기록하며 성장하는 백엔드 개발자입니다!

0개의 댓글