1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

yukicoder No.3 ビットすごろく 解説

Last updated at Posted at 2024-07-19

問題文

前提知識

bit云々

解説

幅優先探索の容量でやる。
$\text{dist}[i]=i$個目のマスに行くときの最短手数。その段階で行けないときは$-1$。
遷移方法
$i$の__builtin_popcountを$e$と置く。
①$\text{dist}[i+e]=\text{dist}[i]+1(i+e\leq n)$
②$\text{dist}[i-e]=\text{dist}[i]+1(i-e>0)$
こんな感じでやれば行ける。
queueには高々$N$回しかpushされず、__builtin_popcountの計算量は$O(1)$。よって実行時間は$O(N)$。

C++での解答例

#include <bits/stdc++.h>
using namespace std;

int main(){
  int n;
  cin >> n;
  //dist[i]=移動手数
  //現段階で行けないときは-1
  vector<int> dist(n+1, -1);
  dist[1] = 1;
  queue<int> que;
  que.push(1);
  while(!que.empty()){
    int u = que.front();
    que.pop();
    //ここからは遷移
    //__builtin_popcount(u)=uの二進数の桁が1になっている数=__builtin_popcount
    //uから1手で行けるのはu+__builtin_popcountかu-__builtin_popcount
    if(u + __builtin_popcount(u) <= n && dist[u + __builtin_popcount(u)] == -1) {
      dist[u + __builtin_popcount(u)] = dist[u] + 1;
      que.push(u + __builtin_popcount(u));
    }
    if(u - __builtin_popcount(u) > 0 && dist[u - __builtin_popcount(u)] == -1) {
      dist[u - __builtin_popcount(u)] = dist[u] + 1;
      que.push(u - __builtin_popcount(u));
    }
  }
  cout << dist[n] << endl;
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?