首页 > 其他分享 >I. 乒乓球赛

I. 乒乓球赛

时间:2025-01-19 21:45:44浏览次数:1  
标签:int cin long 100005 ans 乒乓球赛

  • 很有意思的一道题目,正好这个学期自己也挺关心乒乓球的~
  • \(n\leq 10^5\) 直接递推就好了。要推数学公式的话也不难。分类讨论找一下规律,注意到10平之后一定是双方各有胜负,区别只在于先后顺序,故方案数可以表示为2的次幂
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long f[21][12][12];
long long g[100005][2];
int a[100005],b[100005];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i]>>b[i];
			if(a[i]>b[i])
			{
				swap(a[i],b[i]);
			}
		}
		memset(f,0,sizeof(f));
		f[0][0][0]=1;
		for(int i=1;i<=min(20,n);i++)
		{
			if(a[i]==-1&&b[i]==-1)
			{
				for(int j=max(0,i-11);j<=min(i,11);j++)
				{
					int k=i-j;
					if(i!=n&&(j==11||k==11))
					{
						continue;
					}
					if(j)
					{
						f[i][j][k]+=f[i-1][j-1][k];
					}
					if(k)
					{
						f[i][j][k]+=f[i-1][j][k-1];
					}
					f[i][j][k]%=mod;
				}
			}
			else
			{
				if(a[i]<=11&&b[i]<=11&&a[i]+b[i]==i)
				{
					if(i!=n&&(a[i]==11||b[i]==11))
					{
						continue;
					}
					if(a[i])
					{
						f[i][a[i]][b[i]]+=f[i-1][a[i]-1][b[i]];
						if(a[i]!=b[i])
						{
							f[i][b[i]][a[i]]+=f[i-1][b[i]][a[i]-1];
						}
					}
					if(b[i])
					{
						f[i][a[i]][b[i]]+=f[i-1][a[i]][b[i]-1];
						if(a[i]!=b[i])
						{
							f[i][b[i]][a[i]]+=f[i-1][b[i]-1][a[i]];
						}
					}
					f[i][a[i]][b[i]]%=mod;
					f[i][b[i]][a[i]]%=mod;
				}
			}
		}
		if(n<=20)
		{
			int ans=0;
			for(int j=max(0,n-11);j<=min(n,11);j++)
			{
				if(j>=11||n-j>=11)
				{
					ans=(ans+f[n][j][n-j])%mod;
				}
			}
			cout<<ans<<"\n";
		}
		else
		{
			if(a[21]==-1&&b[21]==-1||a[21]==10&&b[21]==11)
			{
				g[21][0]=g[21][1]=f[20][10][10];
			}
			else
			{
				g[21][0]=g[21][1]=0;
			}
			for(int i=22;i<n;i++)
			{
				if(i%2==0)
				{
					if(a[i]==-1&&b[i]==-1||a[i]==b[i]&&b[i]==i/2)
					{
						g[i][0]=(g[i-1][0]+g[i-1][1])%mod;
					}
					else
					{
						g[i][0]=0;
					}
				}
				else
				{
					if(a[i]==-1&&b[i]==-1||a[i]==i/2&&b[i]==(i+1)/2)
					{
						g[i][0]=g[i][1]=g[i-1][0];
					}
					else
					{
						g[i][0]=g[i][1]=0;
					}
				}
			}
			if(n%2==0&&((a[n]==-1&&b[n]==-1)||(a[n]==n/2-1&&b[n]==n/2+1)))
			{
				cout<<(g[n-1][0]+g[n-1][1])%mod<<"\n";
			}
			else
			{
				cout<<0<<"\n";
			}
		}
	}
	return 0;
}

标签:int,cin,long,100005,ans,乒乓球赛
From: https://www.cnblogs.com/watersail/p/18680222

相关文章