Codeforces Round #732 (Div. 2) D. AquaMoon and Chess(排列组合/组合数)
Cirno gave AquaMoon a chessboard of size 1×𝑛1×n. Its cells are numbered with integers from 11 to 𝑛n from left to right. In the beginning, some of the cells are occupied with at most one pawn, and other cells are unoccupied.
In each operation, AquaMoon can choose a cell 𝑖i with a pawn, and do either of the following (if possible):
- Move pawn from it to the (𝑖+2)(i+2)-th cell, if 𝑖+2≤𝑛i+2≤n and the (𝑖+1)(i+1)-th cell is occupied and the (𝑖+2)(i+2)-th cell is unoccupied.
- Move pawn from it to the (𝑖−2)(i−2)-th cell, if 𝑖−2≥1i−2≥1 and the (𝑖−1)(i−1)-th cell is occupied and the (𝑖−2)(i−2)-th cell is unoccupied.
You are given an initial state of the chessboard. AquaMoon wants to count the number of states reachable from the initial state with some sequence of operations. But she is not good at programming. Can you help her? As the answer can be large find it modulo 998244353998244353.
Input
The input consists of multiple test cases. The first line contains a single integer 𝑡t (1≤𝑡≤100001≤t≤10000) — the number of test cases.
The first line contains a single integer 𝑛n (1≤𝑛≤1051≤n≤105) — the size of the chessboard.
The second line contains a string of 𝑛n characters, consists of characters "0" and "1". If the 𝑖i-th character is "1", the 𝑖i-th cell is initially occupied; otherwise, the 𝑖i-th cell is initially unoccupied.
It is guaranteed that the sum of 𝑛n over all test cases does not exceed 105105.
Output
For each test case, print the number of states that reachable from the initial state with some sequence of operations modulo 998244353998244353.
Example
input
Copy
6
4
0110
6
011011
5
01010
20
10001111110110111000
20
00110110100110111101
20
11101111011000100010
output
Copy
3
6
1
1287
1287
715
注意到题目给的移动的限制,实际上就是相邻的两个1可以接力一样地来回移动且不能分开。同时如果有连续的一串1,有奇数个1的话有一个1实际上永远不会动(把这个1去掉即可,因为最终得到的所有的状态的这个位置都是1,当然随便去掉哪个都ok),其他相邻的1两两一组可以来回跑,如果有偶数个1相邻的1两两一组可以来回跑。所以最终就转换成了一个排列组合问题:设n为组数(两个相邻的1为一组),m为0的个数,求n球入m不同盒的方案数,答案就是。
#include <bits/stdc++.h>
using namespace std;
int n;
#define LL long long
#define p 998244353
const int maxn=1000005;
void extend_gcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1,y=0;
return;
}
extend_gcd(b,a%b,y,x);
y-=a/b*x;
}
LL inv[maxn+10];
LL f[maxn+10];
void init(){//阶乘及其逆元打表
f[0]=1;
for(int i=1;i<=maxn;i++){
f[i]=f[i-1]*i%p;
}
LL x,y;
extend_gcd(f[maxn],p,x,y);//先求出f[N]的逆元,再循环求出f[1~N-1]的逆元
inv[maxn]=(x%p+p)%p;
for(int i=maxn-1;i>=1;i--){
inv[i]=inv[i+1]*(i+1)%p;
}
}
LL C(LL n,LL m){
if(n==m||m==0)return 1;
return (f[n]*inv[m]%p*inv[n-m]%p)%p;
}
int main() {
int t;
cin >> t;
init();
while(t--) {
string s;
int nn;
cin >> nn;
cin >> s;
int n = 0, m = 0;
int lst = -1;
for(int i = 0; i < s.size(); i++) {
if(i == 0) {
if(s[0] == '0') m++;
else {
lst = 0;
}
continue;
}
if(s[i] == '0') {
m++;
if(s[i - 1] == '1') {
int len = i - lst;
n += len / 2;
}
} else {
if(s[i - 1] == '0') {
lst = i;
}
}
}
if(s[s.size() - 1] == '1') {
int len = s.size() - lst;
n += len / 2;
}
cout << C(n + m, m) << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-07-13 VS Code配置C++环境: Unable to start debugging. Unexpected GDB output from command报错
2020-07-13 Codeforces Round #655 (Div. 2) C. Omkar and Baseball(思维)