ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2019 ICPC Asia-East Continent Final 部分题题解

2020-06-29 21:55:41  阅读:423  来源: 互联网

标签:ch 格子 int 题解 Asia read res Continent Mod


题面

Problem B. Black and White

题目大意:有一个\(n\) \(\times\) \(m\)的网格,网格之中的格子有黑白两种颜色。
被(0,0),(0,1),(1,0),(1,1)包围的格子是白色,一个格子周围的四个格子的颜色与其都不相同。
现要从(0,0)走到(n,m),每次只能向上或向右走。
给定\(k\),求满足条件的路径数量,使得这条路径左边的白格子数-黑格子数=\(k\)。
多组数据。
\(n,m,|w| \leq 1e5\),\(T \leq 100\)
题解:
设当前白格子数-黑格子数为\(w\)。
发现每次如果只走一步,我们没法判断当前的\(w\)的变化量。那么考虑走两步。
如果每次都走两步的话,那无非就四种情况:
1.\(\rightarrow \rightarrow\)
2.\(\uparrow \uparrow\)
3.\(\uparrow \rightarrow\)
4.\(\rightarrow \uparrow\)
前两种情况对\(w\)无影响,而3,4这两种情况可能会对\(w\)造成影响。
考虑枚举3,4操作的总次数\(p\),以及4操作的次数\(q\)。
通过打表,可以发现一个式子:

\[\lfloor \frac{p+1}{2} \rfloor - q = k \]

由此,我们只需要枚举\(p\),就能得到合法的\(q\)了。
现在考虑统计方案数。
设\(x=\frac{n+m}{2}\),那么相当于在\(x\)次操作中任选\(p\)次,又在\(p\)次中任选\(q\)个。
然后情况1,2的组合,就是在\(x-p\)次中选\(\frac{n-p}{2}\)次。也就是三个组合数。
注意所有这些要除以2的地方都要求是偶数才有意义。
如果\(n+m\)是奇数,讨论一下第一步怎么走,然后正常算两次就好了。
时间复杂度:\(O(Tn)\)
代码:

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define F(x,y,z) for(re x=y;x<=z;x++)
#define FOR(x,y,z) for(re x=y;x>=z;x--)
typedef long long ll;
#define I inline void
#define IN inline int
#define STS system("pause")
template<class D>I read(D &res){
	res=0;register D g=1;register char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')g=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		res=(res<<3)+(res<<1)+(ch^48);
		ch=getchar();
	}
	res*=g;
}
const int Mod=998244353,N=100010;
int T,fac[101000],inv[101000];
I add(int &x,int y){(x+=y)>=Mod?x-=Mod:0;}
IN Plus(int x,int y){(x+=y)>=Mod?x-=Mod:0;return x;}
IN Pow(int x,int y=Mod-2){
	re res=1;
	while(y){
		if(y&1)res=(ll)res*x%Mod;
		x=(ll)x*x%Mod;
		y>>=1;
	}
	return res;
}
IN C(int x,int y){if(x<y)return 0;return (ll)fac[x]*inv[y]%Mod*inv[x-y]%Mod;}
I init(){
	fac[0]=1;
	F(i,1,N)fac[i]=(ll)fac[i-1]*i%Mod;
	inv[N]=Pow(fac[N]);
	FOR(i,N-1,0)inv[i]=(ll)inv[i+1]*(i+1)%Mod;
}
IN solve(int n,int m,int k){
	if(!n||!m)return k==0?1:0;
	re x=(n+m)>>1,ans=0;
//	cout<<n<<" "<<m<<" "<<k<<" "<<x<<endl;
	for(re p=0,q;p<=x;p++){
		q=((p+1)>>1)-k;
		if(q<0||q>p||((n-p)&1)||p>n)continue;
//		cout<<"!"<<p<<" "<<q<<endl;
		add(ans,(ll)C(x,p)*C(p,q)%Mod*C(x-p,(n-p)>>1)%Mod);
	}
	return ans;
}
int n,m,k;
int main(){
	read(T);init();
	while(T--){
		read(n);read(m);read(k);
		if(!((n+m)&1))printf("%d\n",solve(n,m,k));
		else printf("%d\n",Plus(solve(n-1,m,-k),solve(n,m-1,(n&1)-k)));
	}
	return 0;
}
/*
5
1 1 0
1 1 -1
2 2 1
2 2 0
4 4 1
*/

标签:ch,格子,int,题解,Asia,read,res,Continent,Mod
来源: https://www.cnblogs.com/Purple-wzy/p/13210542.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有