CF1545B AquaMoon and Chess

CF1545B AquaMoon and Chess

题目大意

你有一个长为 \(n\) 的棋盘,这个棋盘上有一些棋子,你可以进行如下操作:

如果第 \(i + 2\) 个位置是空的,且第 \(i + 1\) 个位置非空,则可以将第 \(i\) 个位置的棋子挪到第 \(i + 2\) 个位置 (\(i + 2 \leq n\)).

如果第 \(i - 2\) 个位置是空的,且第 \(i - 1\) 个位置非空,则可以将第 \(i\) 个位置的棋子挪到第 \(i - 2\) 个位置 (\(i - 2 \geq 1\)).

现在将给出一个棋盘的初始状态,求可以通过上述操作可以到达的状态数,你可以进行任意次操作,答案对 \(998244353\) 取模.

分析

考虑得到一个性质:两个1放在一起,不可以也不会分离,并且其可以任意移动。

我们发现,最终状态可以忽略单个1的位置,只考虑0与两个1的个数,进行排列。

0的数量为a个,1的数量为b个,则最后答案为C(a+b,a)

Ac_code

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;

const int N = 1e5 + 10,mod = 998244353;

int fact[N],infact[N];
int n;

int ksm(int a,int b)
{
    int res = 1;
    while(b)
    {
        if(b&1) res = 1ll*res*a%mod;
        a = 1ll*a*a%mod;
        b>>=1;
    }
    return res;
}

void init()
{
    fact[0] = infact[0] = 1;
    for(int i=1;i<N;i++) fact[i] = 1ll*fact[i-1]*i%mod;
    infact[N-1] = ksm(fact[N-1],mod-2);
    for(int i=N-2;i;i--) infact[i] = 1ll*infact[i+1]*(i+1)%mod;
}

int C(int a,int b)
{
    return 1ll*fact[a]*infact[b]%mod*infact[a-b]%mod;
}

int main()
{
    init();
    int T;cin>>T;
    while(T--){
        string s;
        cin>>n>>s;
        int a=0,b=0;
        for(int i=0;i<n;i++)
        {
            if(s[i]=='0') a++;
            else 
            {
                if(i+1<n&&s[i+1]=='1') 
                {
                    b++;i++;
                }
            }
        }
        cout<<C(a+b,a)<<'\n';
    }
    return 0;
}
posted @ 2022-09-07 15:42  艾特玖  阅读(35)  评论(0)    收藏  举报