Official

A - Non-Adjacent Flip Editorial by nok0


[1] \(1\) の個数で場合分けする

\(S\) に含まれる 1 の個数を \(k\) 個とします。

操作によって、\(k\) がどのように変化するか考えると、\(0,+2,-2\) のいずれかなので、\(k\) が奇数の場合は条件を達成できません。以下偶数の場合を考えます。

  • \(k=0\) の場合

明らかです。

  • \(k\geq 4\) の場合

表向きのコインの番号を 左から順に \(x_1,x_2,\ldots,x_k\) とします。 このとき、コイン \(1\) とコイン \(x_{\frac{k}{2}+1}\) に操作し、コイン \(2\) とコイン \(x_{\frac{k}{2}+2}\) に操作し、と順に行うことで、\(\frac{k}{2}\) 回の操作で条件を達成可能です。

  • \(k=2\) の場合

表向きのコインが隣接していない場合、答えは \(1\) です。 以下、隣接している場合を考え、左にあるコインの番号を \(x\) とします。

\(x\geq 3\) の場合、コイン \(1\)\(x\) に操作 \(\to\) コイン \(1\)\(x+1\) に操作 とすることで \(2\) 回の操作で条件を達成可能です。

また、\(x+1\leq N-2\) の場合も、コイン \(x+1\)\(N\) に操作 \(\to\) コイン \(x\)\(N\) に操作 とすることで \(2\) 回の操作で条件を達成可能です。

これら二つの条件をどちらも満たさないのは、\(x<3\) かつ \(x+1 > N-2\) のときで、これは \(N=3,4\) のときに限られます。

\(N=3\) のとき、\(S\)011 または 110 ですが、コイン \(1\),\(3\) 以外に操作が出来ないことから、条件は達成不可能です。

\(N=4\) かつ \(x<3\) かつ \(x+1 > N-2\) を満たす \(S\)0110 です。このとき、\(3\) 回の操作で条件を達成可能です。(方法:0110\(\to\)1111\(\to\)0101\(\to\)0000)また、\(2\) 回の操作で条件を達成不可能なことも、全探索により示せます。

これらの条件は全て \(\mathrm{O}(N)\) で判定可能です。


[2] 実装例

C++:

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

int solve() {
    int n;
    string s;
    cin >> n >> s;
    int one = count(s.begin(), s.end(), '1');
    if(one & 1) return -1;
    bool adj = 0;
    for(int i = 0; i < n - 1; i++)
        if(s[i] == '1' and s[i] == s[i + 1]) adj = 1;
    if(one != 2 or !adj) return one / 2;
    if(n == 3) return -1;
    if(n == 4 and s == "0110") return 3;
    return 2;
}

int main() {
    int t;
    cin >> t;
    while(t--) cout << solve() << endl;
}

Python:

def solve():
    n = int(input())
    s = input()
    k = s.count("1")
    if k & 1:
        return -1
    adj = s.count("11")
    if k >= 4 or k == 0 or not adj:
        return k // 2
    if n == 3:
        return -1
    if s == "0110":
        return 3
    return 2


t = int(input())
for _ in range(t):
    print(solve())

posted:
last update: