seriruの技術屋ブログ

競技プログラミングやゲーム開発など技術に関することを発信します

AtCoder Beginner Contest 19 C 高橋くんと魔法の箱

問題

atcoder.jp

問題概要

 f(x) = f(2x) となる関数  f(X) がある。
 A_i\ ...\ A_n の全ての整数をこの関数に入力した結果、何種類の整数が出力されるか答えよ。

考察

 f(x) = f(2x) f(2x) = f(4x) から  f(x) = f(4x)

一般化すると  f(x) = f(mx)  (m は任意の整数  ) となる。

すなわち、 f(A_i) = A(A_j) となるのは  A_i, A_j を奇数になるまで2で割り続けた結果、等しくなったとき。

よって、 A_i を奇数になるまで割り続けた結果をHashMapなどに入れておき、何種類の整数が存在するかを数えればよい。

 f(x) = f(2x) = f(4x) =\ ...\ f(mx)\ =\ ... に気づけなかったのが痛かった。

コード

#include <iostream>
#include <vector>
#include <map>
using namespace std;

int main() {
  int n;
  cin >> n;
  vector<long long> a(n);
  map<long long,int> check;
  for (int i = 0; i < n; i++) {
    scanf("%lld", &a[i]);
  }

  for (auto& itr : a) {
    while (itr % 2 == 0) {
      itr /= 2;
    }
  }

  ll ans = 0;
  for (auto itr : a) {
    if (check[itr] == 0) {
      check[itr] = 1;
      ans += 1;
    }
  }

  cout << ans << endl;
}