​Problem - 1545B - Codeforces​

 

题意:

1*n的棋盘,初始某些位置可能有棋子

每次可以选择一个棋子,如果它的右边第一个有棋子且第二个无棋子,或者它的左边第一个有棋子且第二个无棋子,就可以把这个棋子跳到那个无棋子的位置

操作可以进行任意次

问棋盘可能有多少种局面

 

画一画可以发现,操作相当于把两个1往0的位置推一格,空出来的那个位置补0

把每连续的两个1看作一个整体,一个0是一个整体,无论怎么操作,整体的数目是不变的

1的整体可以和0的整体任意换

所以设0的整体有a个,1的整体有b个,答案是C(a+b,b)

 



#include<bits/stdc++.h>

using namespace std;

const int mod=998244353;

char s[100004];
int inv[100004];

int main()
{
inv[1]=1;
for(int i=2;i<=100000;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
int T,n,a,b,ans,tag;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
scanf("%s",s+1);
a=0;
b=0;
tag=0;
for(int i=1;i<=n;++i)
if(s[i]=='0')
{
++a;
tag=0;
}
else
{
if(!tag) tag=1;
else
{
++b;
tag=0;
}
}
ans=1;
for(int i=2;i<=a+b;++i) ans=1ll*ans*i%mod;
for(int i=2;i<=a;++i) ans=1ll*ans*inv[i]%mod;
for(int i=2;i<=b;++i) ans=1ll*ans*inv[i]%mod;
printf("%d\n",ans);
}
}


 


作者:xxy