cf1545 B. AquaMoon and Chess

题意:

你有一个长为 n 的棋盘,这个棋盘上有一些棋子,你可以进行如下操作:

如果第 i + 2 个位置是空的,且第 i + 1 个位置非空,则可以将第 i 个位置的棋子挪到第 i + 2 个位置 (\(i + 2 \leq n\))

如果第 i - 2 个位置是空的,且第 i - 1i−1 个位置非空,则可以将第 i 个位置的棋子挪到第 i - 2 个位置 (\(i - 2 \geq 1\))

现在将给出一个棋盘的初始状态,求可以通过上述操作可以到达的状态数,你可以进行任意次操作,取模.

思路:

把字符分组,两个相邻的1(即“11”)为一组,每个0自成一组,剩下每个单独的1自成一组。

则“11”可以自由移动,“1”与“0”的相对位置不变。

所以忽略单独的1,剩下的组随便组合。设有 x 个“11”和 y 个“0”,答案是 \(C(x+y,x)\)

这玩意还挺难想明白的。还有种思考方法:把单独的1算到它后面紧邻的0上面去,即“10”

分组方法:https://codeforces.com/blog/entry/92739?#comment-815214

几个例子:https://codeforces.com/blog/entry/92739?#comment-815690

void sol() {
    cin >> n >> s + 1;
    int c0 = 0, c11 = 0;
    for(int i = 1; i <= n; i++) {
        if(s[i] == '0') c0++;
        else if(i < n && s[i+1] == '1') c11++, i++;
    }
    cout << C(c0 + c11, c0) << endl;
}
posted @ 2022-04-07 23:52  Bellala  阅读(38)  评论(0)    收藏  举报