0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AtCoder】ABC301 D - Bitmask を二分探索問題と勘違いしていた(解けた)

Last updated at Posted at 2024-06-04

【AtCoder】ABC301 D - Bitmask を二分探索問題と勘違いしていた

異端な解き方をしたようなのでメモ。

問題

考えたこと

Sの長さは最大60。
?の個数も最大60。
→単調増加の世界にできたら二分探索ができそう。

二分探索できるか検討してみる

例えばN=184、S="10?1??0?"の場合を考えてみる。
image.png

※図における「AC」と「WA」は公式解説動画の二分探索でよく使われている「正解ゾーン」と「不正解ゾーン」の意味。

?部分だけをbitとして持った64bit整数型で二分探索できそう。
ではどこから開始するか。
二分探索するためには絶対に正解であるACゾーンと、絶対に不正解であるWAゾーンを指定しなければならない。

ACゾーンの決定

?が全て0だったら最小値なのでACとなり得るか?
→ NO。前述の例の場合、Nが143などであればACではない。しかし全ての?が0でN以下にできないならばこの時点で-1を出力して終了すれば良い。この前提を踏まえた上であれば、ACゾーンを0から開始して良い。

WAゾーンの決定

これはシンプルに?を全て1にした場合の数+1と言える。前述の例で言えば190。この値は実現不可能なので正解になり得ない。

実装

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;

auto solve(string S, ll N) -> ll {
    vll indicies;
    for (ll i = S.size() - 1; i >= 0; --i) {
        if (S[i] == '?') {
            indicies.push_back(i);
        }
    }
    auto to_ll = [&](ll m) {
        string s(S);
        for (ll i = 0; i < indicies.size(); ++i) {
            s[indicies[i]] = (m >> i) & 1 ? '1' : '0';
        }
        ll n = 0;
        ll v = 1;
        for (ll i = s.size() - 1; i >= 0; --i) {
            n += v * (s[i] - '0');
            v *= 2;
        }
        return n;
    };
    if (N < to_ll(0)) {
        return -1;
    }
    ll ac = 0;
    ll wa = 1LL << indicies.size();
    while (wa - ac > 1) {
        ll wj = (wa + ac) / 2;
        if (N >= to_ll(wj))
            ac = wj;
        else
            wa = wj;
    }
    return to_ll(ac);
}
int main() {
    string S;
    cin >> S;
    ll N;
    cin >> N;
    cout << solve(S, N) << endl;
    return 0;
}

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?