문제 개요
정수 배열이 주어졌을 때, 배열의 값들로 만들 수 있는 모든 쌍(pair) 중에서 두 원소에 대한 XOR 연산 결과가 홀수가 되는 쌍의 총 개수를 구하는 것이 이 글의 목표입니다.
XOR 연산의 진리표는 아래와 같습니다.
| A | B | A XOR B |
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 1 | 0 |
진리표에서 알 수 있듯이 XOR 연산은 두 비트가 서로 다를 때만 1을 반환합니다. 즉, 짝수(최하위 비트가 0)와 홀수(최하위 비트가 1)를 짝지으면 그 결과는 반드시 홀수가 됩니다. 이 성질이 바로 문제 해결의 핵심입니다.
입력 및 출력 예시
입력 − int arr[] = {2, 8, 1, 5, 11}
출력 − 홀수 XOR을 가지는 쌍의 개수 − 6
설명 −
| a1 | a2 | a1 XOR a2 |
| 2 | 8 | 10 |
| 2 | 1 | 3 |
| 2 | 5 | 7 |
| 2 | 11 | 9 |
| 8 | 1 | 9 |
| 8 | 5 | 13 |
| 8 | 11 | 3 |
| 1 | 5 | 4 |
| 1 | 11 | 10 |
| 5 | 11 | 14 |
위 표에서 볼드 처리된 값이 홀수인 경우로, 총 6개의 쌍이 조건을 만족합니다.
해결 접근 방법
쌍을 만들 정수 배열을 입력받습니다.
배열의 크기를 계산하고, 이후 처리를 위해 함수에 데이터를 전달합니다.
홀수 XOR 결과를 만드는 쌍의 개수를 저장할 임시 변수 count를 선언합니다.
i를 0부터 배열 크기까지 순회하는 FOR 루프를 시작합니다.
루프 내부에서 arr[i] % 2 == 0이면 even_XOR을 1 증가시키고, 그렇지 않으면 odd_XOR을 1 증가시킵니다.
count를 odd_XOR * even_XOR로 설정합니다. 짝수와 홀수를 하나씩 짝지은 조합만 홀수 XOR을 만들기 때문입니다.
count를 반환합니다.
결과를 출력합니다.
이 방법은 모든 쌍을 직접 검사하는 O(n²) 완전 탐색 대신, 배열을 한 번만 순회하여 O(n) 시간 복잡도로 답을 구할 수 있다는 장점이 있습니다.
예제 코드
#include <iostream>
using namespace std;
//Count pairs with Odd XOR
int Odd_XOR(int arr[], int size){
int count = 0;
int odd_XOR = 0;
int even_XOR = 0;
for (int i = 0; i < size; i++){
if (arr[i] % 2 == 0){
even_XOR++;
}
else{
odd_XOR++;
}
}
count = odd_XOR * even_XOR;
return count;
}
int main(){
int arr[] = { 2, 6, 1, 4 };
int size = sizeof(arr) / sizeof(arr[0]);
cout<<"Count of pairs with Odd XOR are: "<<Odd_XOR(arr, size);
return 0;
}
실행 결과
위 코드를 실행하면 다음과 같은 출력이 생성됩니다 −
Count of pairs with Odd XOR are: 3
배열 {2, 6, 1, 4}에는 짝수가 3개(2, 6, 4), 홀수가 1개(1) 있으므로, 3 × 1 = 3개의 쌍이 홀수 XOR 결과를 만족하게 됩니다.