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;
}

浙公网安备 33010602011771号