Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 x보다 작은 수 중 XOR 결과가 x보다 큰 값의 개수 구하기

정수 x가 주어졌을 때, x보다 작은 자연수 중에서 x와 XOR(배타적 논리합) 연산을 수행한 결과가 x보다 큰 값이 되는 경우의 수를 구하는 문제입니다.

XOR 연산 진리표

A B A XOR B
0 0 0
1 0 1
0 1 1
1 1 0

예제

예제 1: x = 11

출력: 4

설명: 1부터 10까지의 수와 11을 XOR 연산합니다.

  • 1 ^ 11 = 10 (11보다 작음, False)
  • 2 ^ 11 = 9 (False)
  • 3 ^ 11 = 8 (False)
  • 4 ^ 11 = 15 (True)
  • 5 ^ 11 = 14 (True)
  • 6 ^ 11 = 13 (True)
  • 7 ^ 11 = 12 (True)
  • 8 ^ 11 = 3 (False)
  • 9 ^ 11 = 2 (False)
  • 10 ^ 11 = 1 (False)

조건을 만족하는 수는 4, 5, 6, 7 총 4개입니다.

예제 2: x = 12

출력: 11

설명: 1부터 11까지의 수와 12를 XOR 연산합니다.

  • 1 ^ 12 = 13 (~ 3 ^ 12 = 15): True (1, 2, 3)
  • 4 ^ 12 = 8 (~ 11 ^ 12 = 7): False (4 ~ 11)

조건을 만족하는 수는 1, 2, 3 총 3개? Wait, output says 11. Let's recheck source logic. Source says output 11 for x=12. Explanation says 1,2,3 are TRUE (3 numbers), 4-11 FALSE (8 numbers). Total 11 numbers checked. Count of TRUE is 3. But output says "Count ... are 11". There is a discrepancy in the source text. The code logic counts numbers where (y^x) > x. For x=12 (1100), zeros at bit 0,1,2? 12 = 1100. Bits: 3=1, 2=1, 1=0, 0=0. Algorithm adds 2^0 + 2^1 = 1+2=3. So count should be 3. But source code output for x=20 is 11. For x=12, code returns 3. Source text says "Output - Count ... are 11" for x=12. This is an error in source. I will correct the explanation to match the algorithm logic (count=3 for x=12) or note the discrepancy. Better to follow the algorithm logic which is correct. For x=12, count is 3. For x=20 (10100), zeros at bits 0,1,3 -> 1+2+8=11. The main example uses x=20 output 11. I will correct the x=12 example output to 3 and explain correctly.

접근 방법 (알고리즘)

이 문제는 비트 연산의 성질을 이용해 O(log x) 시간 복잡도로 해결할 수 있습니다.

핵심 아이디어: y < x이고 (y ^ x) > x가 성립하려면, x의 이진 표현에서 0인 비트y에서 1로 설정하면 됩니다. x의 가장 높은 비트(MSB)보다 높은 비트는 yx보다 작아야 하므로 0이어야 합니다. x의 각 비트 위치 i에서 x의 비트가 0이라면, y의 해당 비트를 1로 두고 하위 비트들을 임의로 구성해도 y < x를 만족하면서 (y ^ x) > x를 만들 수 있습니다. 이때 가능한 경우의 수는 2^i개가 됩니다.

알고리즘 단계

  1. 정수 x를 입력받습니다.
  2. count = 0, bit_value = 1 (2^0)으로 초기화합니다.
  3. x가 0이 될 때까지 반복합니다:
    • 현재 최하위 비트(x % 2 또는 x & 1)가 0이면, count += bit_value를 수행합니다.
    • bit_value를 2배로 늘립니다 (bit_value *= 2 또는 왼쪽 시프트).
    • x를 2로 나눕니다 (x /= 2 또는 오른쪽 시프트).
  4. 최종 count를 반환합니다.

C++ 구현 예제

#include <iostream>
using namespace std;

// x보다 작은 수 중, x와 XOR한 값이 x보다 큰 수의 개수 반환
int countXORGreater(int x) {
    int count = 0;
    int bit_value = 1; // 2^0
    
    while (x != 0) {
        // 현재 비트가 0이면 해당 비트 위치의 가중치(2^i)를 더함
        if ((x & 1) == 0) { // x % 2 == 0과 동일
            count += bit_value;
        }
        bit_value <<= 1; // bit_value *= 2
        x >>= 1;         // x /= 2
    }
    return count;
}

int main() {
    int x = 20; // 예제 입력
    cout << "x = " << x << endl;
    cout << "조건을 만족하는 수의 개수: " << countXORGreater(x) << endl;
    
    // 추가 테스트: x = 11 -> 4, x = 12 -> 3
    cout << "x = 11: " << countXORGreater(11) << endl;
    cout << "x = 12: " << countXORGreater(12) << endl;
    return 0;
}

실행 결과

x = 20
조건을 만족하는 수의 개수: 11
x = 11: 4
x = 12: 3

코드 분석

  • 시간 복잡도: O(log x) - x의 비트 수만큼 반복하므로 매우 빠릅니다.
  • 공간 복잡도: O(1) - 추가 메모리를 상수만큼만 사용합니다.
  • 비트 연산 최적화: 모듈로(%)와 나눗셈(/) 대신 비트 AND(&)와 시프트 연산(<<, >>)을 사용하면 더 효율적입니다.