[JAVA] 백준 21396 : 이진수 더하기

2025. 7. 21. 17:57·백준/Java

백준 21396 : 이진수 더하기

문제 설명

테스트 수 T회

N개의 수 v[i]를 입력으로 받아올림이 없는 이진수 덧셈의 결과가 x인 갯수를 구하는 문제입니다.

입력값이 크므로 long 자료형을 사용해야합니다. (35%에서 틀렸을 경우 참고)


풀이 방법

  • 핵심은 XOR 연산의 특징을 이용하는 것입니다.
    • 받아올림이 없는 이진수 덧셈 : 1(2) + 1(2) = 0(2) , 1(2) + 0(2) = 1(2), 0(2) + 0(2) = 0(2)
    • 즉, 두개의 비트가 다르면 1, 같으면 0을 출력하는 XOR연산과 동일합니다.
  • 임의의 두 수 a, b가 있다고 할 때, a ^ b = x라면, 이는 b = a ^ x와 동일합니다.
  • 즉, 어떤 수 a가 존재할 때 a ^ x가 집합에 존재한다면 (a, a^x)는 조건을 만족하는 쌍입니다.
  • 중복 없이 쌍을 세기 위해 맵(HashMap)을 이용해 각 수의 등장 횟수를 저장해 놓고 쌍을 계산합니다.
  • 단, x = 0인 경우에는 a ^ a = 0이기 때문에, 같은 수끼리 짝짓는 경우를 따로 처리해야 합니다.

코드 (Java)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;

public class Main {
    //    p_21396 : 이진수 더하기
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        while (T-- > 0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            long n = Integer.parseInt(st.nextToken());
            long x = Integer.parseInt(st.nextToken());

            st = new StringTokenizer(br.readLine());
            HashMap<Long, Integer> v = new HashMap<>();
            for (int i = 0; i < n; i++) {
                long value = Integer.parseInt(st.nextToken());
                v.put(value, v.getOrDefault(value, 0) + 1);
            }

            long cnt = 0;
            if (x == 0) {
                for (long k : v.keySet()) {
                    long c = v.get(k);
                    cnt += c * (c - 1);
                }
            } else {
                for (long k : v.keySet()) {
                    long a = v.get(k);
                    long b = v.getOrDefault(k ^ x, 0);
                    cnt += a * b;
                }
            }
            sb.append(cnt / 2).append('\n');
        }
        System.out.print(sb);
    }
}

핵심 로직 설명

  • x == 0일 때는 같은 숫자끼리 짝짓는 경우이므로 c * (c - 1) 방식으로 쌍의 수를 셉니다.
  • x != 0일 때는 a와 a ^ x가 서로 다른 값이므로, 각 값의 빈도수를 곱해 쌍을 셉니다.
  • 쌍은 (a, b)와 (b, a)로 두 번 세어지므로, 마지막 결과를 2로 나누어 중복을 제거합니다.

시간복잡도 & 최적화 포인트

  • 시간복잡도: O(N) (맵을 통한 상수 시간 조회)
  • HashMap을 통해 수의 빈도수를 효율적으로 관리
  • XOR의 대칭성과 성질을 활용하여 연산 최적화

회고

  • XOR 연산의 성질을 떠올리는 것이 핵심 포인트였다.
  • 특히 x = 0일 때 예외 처리를 놓치기 쉬운데, (a ^ a = 0)이므로 동일한 수끼리 짝짓는 논리를 정확히 적용하는 것이 중요했다.
  • 해시맵을 활용한 수의 빈도수 관리가 실전 문제에서도 자주 쓰이므로 익숙해져야 한다.

참고

 

[Algorithms] 비트 연산

Reference. 3460번 이진수, Baekjoon online judge 21396번 이진수 더하기, Baekjoon online judge

velog.io

 

'백준 > Java' 카테고리의 다른 글

[JAVA] 백준 14649 : 문홍안  (0) 2025.07.23
'백준/Java' 카테고리의 다른 글
  • [JAVA] 백준 14649 : 문홍안
2Suchan
2Suchan
github : @KRSuchan
  • 2Suchan
    dev_logs
    2Suchan
  • 전체
    오늘
    어제
    • 분류 전체보기 (42)
      • 백준 (6)
        • Python (2)
        • 알고리즘 (2)
        • Java (2)
      • 프로그래밍 (10)
        • Java (10)
      • Spring (1)
        • 트러블슈팅 (1)
      • DB (1)
        • Redis (1)
      • DevOps (1)
        • Docker (1)
      • 수학 (12)
        • 이산수학 (12)
      • Univ. (11)
        • 캡스톤디자인 (7)
        • 인공지능 (1)
        • 빅데이터 (1)
        • 정보보안 (1)
        • 디자인패턴 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    14649
    20챕터
    21396
    2판
    chapter13
    Chapter14
    Chapter15
    exercise
    GUI
    java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
2Suchan
[JAVA] 백준 21396 : 이진수 더하기
상단으로

티스토리툴바