D. AquaMoon and Chess
题目传送门:
题面:
图截的是Div1的,所以是B。
题目大意:
给你一堆01串,移动方法是“011”可以变成“110”;“110”可以变成“011”,就是对应1可以跨越相邻的1到隔这个1位置的0处。
问你给定01串可以衍生出几种不同排列方法。
思路:
欣君的视频讲解
非常清晰,珠玉在前我就直接偷懒不写思路。
简单说记录11和0的数量。
思路如何转换非常重要,我觉得还是挺难做的,希望自己能在这方面有所涉猎,下次能看出来。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const ll maxn = 3e5 + 10;
ll n;
char a[maxn];
int quick(ll m, ll k) {
ll res = 1 % mod, t = m;
while (k) {
if (k & 1) res = res * t % mod;
t = t * t % mod;
k >>= 1;
}
return res;
}
ll C(ll n, ll m) {
if (n < m) return 0;
if (m > n - m) m = n - m;
long long a = 1, b = 1;
for (int i = 0; i < m; i++) {
a = (a * (n - i)) % mod;
b = (b * (i + 1)) % mod;
}
return a * quick(b, mod - 2) % mod;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
ll x = 0, y = 0, ans = 0;
a[n + 1] = '0';
for (int i = 1; i <= n; i++) {
if (a[i] == '1') ans++;
else {
y++;
x += ans / 2;
ans = 0;
}
}
x += ans / 2;
cout << C(x + y, x) << endl;
}
}