建设城市(city)(【CCF】NOI Online 能力测试2 入门组第三题 )

时间限制: 1.0 秒

空间限制: 256 MB

题目描述

球球是一位建筑师。一天,他收到市长的任务:建设城市。球球打算建造 2n 座高楼。为了保证城市美观,球球做出了如下计划:

  1. 球球喜欢整齐的事物。他希望高楼从左向右排成一行,编号依次为 1∼2n。
  2. 球球喜欢整数,他要求每座高楼的高度都是正整数。
  3. 由于材料限制,高楼的高度无法超过 m。
  4. 球球喜欢中间高,两边低的造型。他要求前 n 座高楼的高度不下降,后 n 座高楼的高度不上升。
  5. 球球打算选两座编号为 x,y 的高楼作为这座城市的地标。他认为只有当这两座高楼高度相等时,才会让城市变得美观。

球球把自己的想法告诉了市长。市长希望得知所有建设城市的方案数。两种方案不同,当且仅当某座高楼的高度在两个方案中不同。这个问题可难倒了球球。球球找到了你,希望你能帮他算出答案。由于答案可能很大,你只需要给出答案对 998244353 取模后的结果。

输入格式

从标准输入读入数据。

仅一行四个整数 m,n,x,y,变量意义见题目描述。

输出格式

输出到标准输出。

仅一行一个整数表示答案。

样例1输入

3 2 1 3

样例1输出

10

样例1解释

所有的方案为:{1,1,1,1},{1,2,1,1},{1,3,1,1},{2,2,2,1},{2,2,2,2},{2,3,2,1},{2,3,2,2},{3,3,3,1},{3,3,3,2},{3,3,3,3}。

样例2输入

1000 1000 535 1477

样例2输出

295916566

思路分析: 

1.只在1~4的条件下(先不考虑x,y)如果一块区域有 n 栋高楼,m 个高度可以选,则相当于 n个相同的球放入 m 个不同的盒子 的方案数,由于楼的高度可以相等,则相当于n+m个相同的球放入 m 个不同的盒子 的方案数,每个盒子至少放一球。由插板法可知方案数C_{n+m-1}^{m-1}

 

2.再考虑条件5,题目没有告诉我们 x,y 是否在 n 的两侧,所以要分情况讨论

    (1)case1:x≤n<y

    枚举 x,y的高度。假设当前 x,y的高度为 i,则:

  • x 左边的 x-1个高楼高度范围为 [1,i]。
  • x 右边 n 左边(包含 nn)的 n-x个高楼高度范围为 [i,m]。
  • n 右边(不包含 n)y左边的 y−n−1 个高楼高度范围为 [i,m]。
  • y 右边的 2n-y个高楼高度范围为 [1,i]。

    根据乘法原理,将以上四种情况相乘即可。

    (2)Case 2:y≤n 或 x,y>n。

      将 [x,y] 中间的高楼看成一个高楼,则相当于C_{n+m-1}^{m-1}*C_{n+x-y+m-1}^{m-1}

 

 

#include<iostream>
using namespace std;
const int mod=998244353;
int m,n,x,y;
long long int ans=0;

int inverse(int x,int mod) {
    int power=mod-2;
    x %= mod;
    int num = 1;
    for (; power; power >>= 1, (x *= x) %= mod)
        if(power & 1) (num *= x) %= mod;
    return num;
}

int cn(int a,int b)//组合数计算 
{
	int sum=1;
	for(int i=1;i<=b;i++)
	{
		sum=sum*(a-b+i)%mod;
		sum=sum*inverse(i,mod)%mod;//求i模mod的逆元 
	}
	return sum; 
}

int main()
{
	cin>>m>>n>>x>>y;
	if(x<=n&&y>=n)//case1情况 
	{
		for(int i=1;i<=m;i++)
			ans+=cn(x+i-1,i-1)*cn(n-x+m-i,m-i)*cn(y-n+m-i,m-i)*cn(2*n-y+i-1,i-1)%mod;
		cout<<ans;
	}
	else
	{
		ans=cn(n+m-1,m-1)*cn(n+m-1-x+y,m-1)%mod;
		cout<<ans;
	}
	return 0;
	
 }  

 

NOI Online能力测试视频版,让我们看看出题人们怎么说!
 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值