Codeforces #309(div2)

分享了作者参加 CodeForces 比赛的经历,并详细解析了三道题目的解题思路及代码实现,特别是针对 C 题的组合数学解法进行了深入探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从来没有写过博客,想想是该写点自己的博客了,但是并不知道该写点什么。

昨晚做的codeforces感觉还不错,排名排到自己的最好成绩div2第118名。

前面两题有点简单,就不多做说明,如果看了题目觉得有困难的同学,可以参考一下我的代码,然后再认真分析一下,应该是没多大问题的。

#include <iostream>
using namespace std;
int main() {
	string str;
	cin >> str;
	int len = str.length();
	int ans = 26 * (len + 1) - len;
	cout << ans << endl;
	return 0;
}//A题的代码

#include <iostream>
#include <map>
#define x first
#define y second
using namespace std;
int main() {
	int N;
	cin >> N;
	map<string, int> mp;
	for (int i = 0; i < N; ++i) {
		string str;
		cin >> str;
		mp[str]++;
	}
	int ans = 0;
	for (auto i : mp) ans = max(i.y, ans);
	cout << ans << endl;
	return 0;
}//B题代码, 用c++11提交

对于C题,我看到这道题目中模(1E9 + 7)这个信息,就感觉是组合数学,然后果然是。

题意大概是,有编号1到K的K种颜色,需对每种颜色画Ci个球,对于第i种颜色,必须比第i + 1到第K种颜色先画完,或许再转述 一下就是,在画第i种颜色的最后一个球之前必须要先画完前面第1种颜色到第i - 1种颜色的所有球。问画完所有颜色的球,有多少种安排方法,答案模(1E9 + 7).

读完题目,很明显的是个组合数学。我就试着推了一下。其实就是上面转述题意的那句话,在画第i种颜色的最后一个球之前必须要先画完前面第1种颜色到第i - 1种颜色的所有球。我觉得这句话理解到了,公式就出来了。

假设前i种颜色的球的个数为sum, 第i种颜色的球有Ci个,这Ci个球种一定有且仅有一个球是在这sum个球当中最后才画的,所以有C(sum - 1, Ci - 1)种方法去安排这Ci- 1个球的位置。然后再递归的去思考第i - 1种颜色,把答案累乘上来就行了。

当然我知道自己的思考或许是有点多余了,因为提交之后给题目上锁,准备去hack一下别人的时候发现有很多不一样的思路,而且都很简洁。所以如果各位觉得我叙述的多余了,还请多多交流,我真的会非常感激的,谢谢!

下面是我C题的代码,至于DE两题,昨晚看见题目就不想看了,确实是有点烦。而且当时D题过了3人,E题过了1人,看见大家都不会, 我就放心了,然后就睡觉了。

ps:确实是因为能力有限,做不了那两道题。哈哈。。。

#include <iostream>
#include <vector>
#define ll long long
#define MOD 1000000007
#define MAXN 1001
using namespace std;
ll fact[MAXN], inverse[MAXN];
ll Power(ll N, ll M) {
	ll ans = 1;
	while (M) {
		if (M & 1) ans = ans * N % MOD;
		N = N * N % MOD;
		M >>= 1;
	}
	return ans;
}
void Prepare() {
	fact[0] = inverse[0] = 1;
	for (int i = 1; i <= MAXN; ++i) {
		fact[i] = fact[i - 1] * i % MOD;
		inverse[i] = Power(fact[i], MOD - 2);
	}
}
ll C(ll N, ll M) {
	if (N < M) return 0;
	return fact[N] * inverse[M] % MOD * inverse[N - M] % MOD;
}
int main() {
	Prepare();
	ll N, sum = 0;
	cin >> N;
	vector<int> vec(N);
	for (int i = 0; i < N; ++i) {
		cin >> vec[i];
		sum += vec[i];
	}
	ll ans = 1;
	for (int i = vec.size() - 1; i >= 0; --i) {
		ll temp = C(sum - 1, vec[i] - 1);
		ans = ans * temp % MOD;
		sum -= vec[i];
	}
	cout << ans << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值