Codeforces Round #732 (Div. 2)(D)
Posted 吃花椒的妙酱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #732 (Div. 2)(D)相关的知识,希望对你有一定的参考价值。
题目大意:给个01串,如果1左右有1,那么可以跨过那个1,比如011可以变成110,求总的序列数。
思路:组合数学
可以发现只有连续两个11才能进行移动,单独的1是不动的,问题转化为用n个11和m个0构造出序列的个数,用隔板法解决问题,C(n+m,m)
当连续奇数个1时,最后会有一个1不动,这个1看作分界线,它左边的11只能向左移动,右边的11只能向右移动1,对答案不影响
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <list>
#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <deque>
using namespace std;
typedef long long ll;
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define scd(v) scanf("%d",&v)
#define scdd(a,b) scanf("%d %d",&a,&b)
#define endl "\\n"
#define IOS ios::sync_with_stdio(false)
#define pb push_back
#define all(v) v.begin(),v.end()
#define int long long
#define mst(v,a) memset(v,a,sizeof(v))
const int N = 1e5+10;
const int mod = 998244353;
int n,m;
int f[N];
char s[N];
ll qsm(int a ,int b )
{
int ans=1,temp=a;
while( b )
{
if( b&1 ) ans = (ans * temp )%mod;
temp = (temp * temp)%mod;
b>>=1;
}
return ans;
}
int C(int n ,int m)
{
return f[n] * qsm(f[n-m],mod-2)%mod * qsm(f[m],mod-2)%mod;
}
signed main()
{
//!!
// freopen("data.txt","r",stdin);
//!!
IOS;
f[0]=1;
_for(i,1,100000) f[i] = f[i-1]*i%mod;
int T;cin>>T;
while(T--)
{
cin>>n;
cin>>(s+1);
int cnt1=0,cnt2=0;
_for(i,1,n-1)
{
if( s[i] == '1' &&s[i+1] =='1') cnt1++,i++;
}
_for(i,1,n)
{
if( s[i] == '0') cnt2++;
}
// cout<<cnt1<<" "<<cnt2<<endl;
cout<<C(cnt1+cnt2,cnt2)<<endl;
}
}
以上是关于Codeforces Round #732 (Div. 2)(D)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #732 (Div. 1&&Div. 2)
Codeforces Round #732 div.2 A-E题解
Codeforces Round #732 (Div. 2) D. AquaMoon and Chess
Codeforces Round #732 (Div. 2) D. AquaMoon and Chess