정수 배열이 주어졌을 때, 배열의 값들로 만들 수 있는 모든 쌍(pair) 중에서 비트 AND 연산 결과가 홀수가 되는 쌍의 총 개수를 구하는 문제입니다.
AND 연산의 진리표
비트 AND 연산은 두 비트가 모두 1일 때만 1을 반환합니다.
| A | B | A & B |
| 0 | 0 | 0 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 1 | 1 |
입력 / 출력 예시
입력 − int arr[] = {2, 5, 1, 8, 9}
출력 − 비트 AND 연산 결과가 홀수인 쌍의 개수: 3
설명 −
| a1 | a2 | a1 & a2 |
| 2 | 5 | 0 |
| 2 | 1 | 0 |
| 2 | 8 | 0 |
| 2 | 9 | 0 |
| 5 | 1 | 1 |
| 5 | 8 | 0 |
| 5 | 9 | 1 |
| 1 | 8 | 0 |
| 1 | 9 | 1 |
| 8 | 9 | 8 |
핵심 아이디어
위 표에서 알 수 있듯이, 두 수의 비트 AND 연산 결과가 홀수가 되려면 두 수 모두 홀수여야 합니다. 그 이유는 홀수의 최하위 비트(LSB)는 항상 1이고, 짝수는 0이기 때문입니다. 따라서 배열에 포함된 홀수의 개수만 세면, 그중 2개를 뽑는 조합 공식 n × (n−1) / 2로 정답을 바로 구할 수 있습니다.
알고리즘 접근 방법
쌍을 만들 정수 배열을 입력받습니다.
배열의 크기를 계산한 뒤, 데이터를 함수에 전달하여 처리합니다.
AND 연산 결과가 홀수가 되는 쌍의 개수를 저장할 임시 변수
count를 생성합니다.i를 0부터 배열 크기까지 반복하는 FOR 루프를 시작합니다.
루프 안에서
arr[i] % 2 == 1(홀수 여부)을 확인하고, 참이면 count를 1 증가시킵니다.count에
count * (count - 1) / 2를 대입하여 쌍의 총 개수를 계산합니다.count를 반환합니다.
결과를 출력합니다.
예제 코드
#include <iostream>
using namespace std;
// 비트 AND 연산 결과가 홀수인 쌍의 개수 세기
int count_pair(int arr[], int size){
int count = 0;
for (int i = 0; i < size; i++){
if ((arr[i] % 2 == 1)){
count++;
}
}
// 홀수 개수에서 2개를 뽑는 조합: nC2
count = count * (count - 1) / 2;
return count;
}
int main(){
int arr[] = {2, 5, 1, 8, 9, 2, 7};
int size = sizeof(arr) / sizeof(arr[0]);
cout<<"비트 AND 연산 결과가 홀수인 쌍의 개수: "<<count_pair(arr, size) << endl;
return 0;
}실행 결과
위 코드를 실행하면 다음과 같은 출력이 생성됩니다.
비트 AND 연산 결과가 홀수인 쌍의 개수: 6
배열 {2, 5, 1, 8, 9, 2, 7}에는 홀수가 4개(5, 1, 9, 7) 포함되어 있으므로, 4 × 3 / 2 = 6개의 쌍이 계산됩니다. 이 방법은 모든 쌍을 일일이 검사하는 O(n²) 방식과 달리 O(n)의 시간 복잡도로 매우 효율적으로 동작합니다.