작성일 :

문제 링크

15917번 - 노솔브 방지문제야!!

설명

여러 개의 자연수가 주어지는 상황에서, 쿼리의 개수 Q (1 ≤ Q ≤ 1,000,000)와 각 쿼리마다 자연수 a가 주어질 때, 각 a가 2의 거듭제곱인지 판별하는 문제입니다.

2의 거듭제곱은 1, 2, 4, 8, 16, … 과 같은 수들입니다. 2의 거듭제곱이면 1을, 아니면 0을 출력합니다.


접근법

2의 거듭제곱은 이진수 표현에서 단 하나의 비트만 1입니다.

비트 연산을 사용하여 효율적으로 판별할 수 있습니다. 어떤 수 a와 -a를 AND 연산하면 가장 오른쪽의 1 비트만 남습니다.

이 결과가 a와 같다면 a는 단 하나의 비트만 1인 수, 즉 2의 거듭제곱입니다.



Code

C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.IO;

namespace Solution {
  class Program {
    static void Main(string[] args) {
      var reader = new StreamReader(new BufferedStream(Console.OpenStandardInput()));
      var writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput()));

      var q = int.Parse(reader.ReadLine()!);
      
      for (var i = 0; i < q; i++) {
        var num = long.Parse(reader.ReadLine()!);
        writer.WriteLine(((num & -num) == num) ? 1 : 0);
      }

      writer.Flush();
    }
  }
}

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int q; cin >> q;
  
  while (q--) {
    ll num; cin >> num;
    cout << (((num & -num) == num) ? 1 : 0) << "\n";
  }

  return 0;
}