Codeforces Round 925 (Div. 3) G. One-Dimensional Puzzle 组合数学

文章讨论了一维拼图问题,其中四种类型的元素不能旋转,只能通过左右端点相连。通过将元素分类为凸和凹,以及利用组合数计算规则,解决了不同数量1和2如何形成连续序列的问题。代码展示了C++实现的解决方案。
摘要由CSDN通过智能技术生成

题目链接

题意

有一个一维拼图,所有元素都需要排成一行,并相互连接,元素的类型正好有 4种,不能旋转,

如果左边元素的右边连接点与右边元素的左边连接点相对,那么两个元素就可以连接起来。谜题中每种类型包含 c1,c2,c3,c4 个元素。如果成功地将所有元素组合成一条长链,那么谜题就算完成了。问:有多少种方法可以做到这一点。

思路

前置知识(相同元素的分配问题):

1.n个相同的球放入m个盒中,盒不为空,则有多少种放法

        插隔板,在n个球形成的 n-1个间隔中选 m-1个分别插入一个隔板,可分成m份且每份都不为空,即C_{n-1}^{m-1}

2.n个相同的球放入m个盒中,盒可为空,则有多少种放法

        将m-1个隔板和n个球看成相同元素排成一列,从(n+m-1)个中选(m-1)个位置来放隔板,即C^{_{n+m-1}^{m-1}}

本题思路:

将元素3看作凸,4看作凹(以右端为准),单独的3能连成一串凸的串,单独的4同理。而1、2可以实现“转向”,1可将凹变为凸,2反之,故1、2是以间隔的方式连接下去的,如…1…2…1…2…

根据1和2的数量分类,当c1==c2时,排列方式可能为1212…,也可能为2121…,则有奇数个空格 _1_2_1_2_, 3和4可放的间隔数不一样,两种情况相加:当abs(c1-c2)==1时,多出一个时,间隔排列形成的间隔数为偶数,3和4可放的间隔数一样;其他,即abs(c1-c2)>1时,不能组成一串,方案数为0。

特判,当c1==c2==0时,只有c3或c4一方为0或双方都为0时有1种排列方式,当c3、c4都不为0时,没有1、2作用不能连接在一起,不成串,有0种排列方式。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e6 + 100, mod = 998244353;
int fac[N], infac[N];

int qsm(int a, int k, int p) {
	int res = 1;
	while (k) {
		if (k & 1) res = res * a % p;
		a = a * a % p;
		k >>= 1;
	}
	return res;
}

//预处理出所给范围内的阶乘和阶乘的逆元
void pre(int n) {
	fac[0] = infac[0] = 1;
	for (int i = 1; i <= n; ++i)
		fac[i] = fac[i - 1] * i % mod;
	infac[n] = qsm(fac[n], mod - 2, mod);
	for (int i = n - 1; i >= 1; --i)
		infac[i] = infac[i + 1] * (i + 1) % mod;
}

//组合数的计算
int C(int a, int b) {
	if (b > a) return 0;
	return fac[a] * infac[b] % mod * infac[a - b] % mod;
}

void solve() {
	int c1, c2, c3, c4;
	cin >> c1 >> c2 >> c3 >> c4;
	if (c1 == c2) {
		if (!c1) {
			if (!c3 || !c4) cout << 1 << '\n';
			else cout << 0 << '\n';
			return;
		}
		else {
			int x = c1;
			int ans1 = C(c3 + x - 1, x - 1) % mod * C(c4 + x, x) % mod;
			int ans2 = C(c4 + x - 1, x - 1) % mod * C(c3 + x, x) % mod;
			cout << (ans1 + ans2) % mod << '\n';
		}
	}
	else if (abs(c1 - c2) == 1) {
		int x = max(c1, c2);
		int ans = C(c3 + x - 1, x - 1) * C(c4 + x - 1, x - 1) % mod;
		cout << ans << '\n';
	}
	else cout << 0 << '\n';
	return;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	pre(2e6 + 10);
	int t = 1;
	cin >> t;
	while (t--) solve();
	return 0;
}

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值