题目
题目大意
给定一个1xn的棋盘,用01序列表示棋盘的初始情况,可以对旗子进行任意次操作:
选择一颗棋子将其移动到i+2或i-2,前提是i+1或i-1处有棋子,即类似跳棋的规则。
问棋盘能有多少种不同的状态。
解题思路
可以通过画图来分析问题,由原本的将相邻的两个棋子分为一组,不论如何移动,分组的情况是不变的,原本有k组两个相邻的,任意移动后,还是有k组,改变得只是他们得相对位置,并且我们无法控制单独出现的棋子的位置,即当0和2确定是1的状态是无法改变的,那么只能改变0,2的。那么答案就是c(num0)(num0+num2);
code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e5+5;
const ll mod=998244353;
ll qsm(ll a,ll b)
{
ll base=a,ans=1;
while(b>0)
{
if(b%2==1)ans=ans*base%mod;
base=base*base%mod;
b>>=1;
}
return ans;
}
void solve()
{
int n,res=1;
cin>>n;
string s;
cin>>s;
ll ans1=0,ans2=0;
for(int i=1;i<s.length();i++)if(s[i]=='1'&&s[i-1]=='1')ans2++,i++;
for(int i=0;i<s.length();i++)if(s[i]=='0')ans1++;
ll num=ans1+ans2;
//cout<<ans1<<" "<<ans2<<endl;
for(int i=1;i<=ans1;i++)
{
res=res*num%mod;
num--;
}
for(ll i=1;i<=ans1;i++)
{
res=res*qsm(i,mod-2)%mod;
}
cout<<res<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)solve();
return 0;
}