Educational Codeforces Round 88 (Rated for Div. 2)

本文解析了Educational Codeforces Round 88的五道题目,包括Berland Poker、New Theatre Square、Mixing Water、Yet Another Yet Another Task和Modular Stability,提供了详细的解题思路和代码实现。

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

Educational Codeforces Round 88 (Rated for Div. 2)

A. Berland Poker

题目大意

给n张卡片,其中m张是jokers,把这n张卡片均分给k个人,问怎么分可以使得拥有最多jokers和第二多jokers的人的jokers数量差值最大。输出这个差值。

Solution

首先尽可能把jokers给一个人,如果该人获得卡片数达到上限,剩下的jokers尽可能均分给其余人。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int n,m,k;
 
int main()
{
	int T;
	scanf("%d",&T);
	while(T --)
	{
		scanf("%d%d%d",&n,&m,&k);
		int t = n / k;
		if(m <= t) printf("%d\n",m);
		else 
		{
			int s;
			if(((m - t) % (k - 1)) == 0)
				s = (m - t) / (k - 1);
			else 
				s = (m - t) / (k - 1) + 1;
			printf("%d\n",t - s);
		}
	}
	return 0;
} 

B. New Theatre Square

题目大意

把白色区域全部铺上砖,砖有两种类型,一种价值为x的1 x 1的瓷砖,一种价值为y的1 x 2的瓷砖,问怎样铺花费最少。

Solution

如果2x <= y ,全铺第一种。
否则,尽可能多的铺第二种,剩余的空用第一种填。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int n,m,x,y;
char s[105][1020];
 
int main()
{
	int T;
	scanf("%d",&T);
	while(T --)
	{
		int numb = 0,numh = 0;
		scanf("%d%d%d%d",&n,&m,&x,&y);
		for(int i = 1;i <= n;i ++)
		{
			getchar();
			for(int j = 1;j <= m;j ++)
			{
				scanf("%c",&s[i][j]);
				if(s[i][j] == '.') numb ++;
				else if(s[i][j] == '*') numh ++;
			} 
		}
		if(2 * x <= y) printf("%d\n",x * numb);
		else 
		{
			int ans = 0;
			for(int i = 1;i <= n;i ++)
				for(int j = 1;j <= m;j ++)
				{
					if(s[i][j] == '.')
					{
						if(j + 1 <= m && s[i][j + 1] == '.')
						{
							numb -= 2;
							ans += y;
							j ++; 
						}
					}
				} 
			printf("%d\n",ans + numb * x);
		}
	}
	return 0;
} 

C. Mixing Water

题目大意

热水的温度是h,冷水的温度是c,目标温度是t。
你可以在一个容器内进行加水操作,使得最终温度尽可能接近t,加水次序必须是热水冷水交替,且第一杯为热水,问最少加几杯水可以使得温度尽可能接近t。

Solution

特殊情况,h == t 输出1.
因为加入水的数量只能是冷水热水相同或者热水比冷水多一杯,所以如果热水影响比冷水大(即热水与目标温度的差值大于目标温度与冷水的差值),那么这个时候多加一杯热水不会使得更靠近目标,直接输出2即可,如果冷水的影响更大,那么就通过加相同数量的冷热水与最终多加的一杯热水抵消来得到更靠近目标温度的效果。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int h,c,t;

inline void solve()
{
	if(h == t) { printf("1\n"); return; }
	if(c == t) { printf("2\n"); return; }
	int chang1 = h - t ,chang2 = t - c;
	if(chang1 == chang2) { printf("2\n"); return; }
	int dou = chang1 - chang2;
	if(dou > 0) printf("2\n");
	else 
	{
		dou = -dou;
		int ss = chang1 / dou * dou;
		double t1 = (double)abs(chang1 - ss) / (double)(chang1 / dou * 2 + 1);
		double t2 = (double)abs(chang1 - (ss + dou)) / (double)(chang1 / dou * 2 + 3);
		if(t1 <= t2) printf("%d\n",chang1 / dou * 2 + 1);
		else printf("%d\n",(chang1 / dou * 2 + 3));
	} 
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T --)
	{
		scanf("%d%d%d",&h,&c,&t);
		solve();
	}
	return 0;
} 

D. Yet Another Yet Another Task

题目大意

给定一个长度为n的序列,选择一段连续的区间,去掉其中最大的数字,使得该段区间的和最大。

Solution

a[i]的大小只有30,所以直接枚举一个最大数字,然后暴力扫区间即可。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int n;
int num[SZ];
int main()
{
	/*
	int T;
	scanf("%d",&T);
	while(T --)
	{
		
	}
	*/
	scanf("%d",&n);
	int ans  = 0;
	for(int i = 1;i <= n;i ++)	scanf("%d",&num[i]);
	for(int i = 1;i <= 30;i ++)
	{
		int sum = 0;
		for(int j = 1;j <= n;j ++)
		{
			if(num[j] > i)
			{
				sum = 0;
			}
			if(num[j] <= i)
			{
				sum += num[j];
				if(sum < 0) sum = 0;
				else ans = max(ans,sum - i);
			}
		}
	}
	printf("%d\n",ans);
	return 0;
} 

E. Modular Stability

题目大意

给定一个n和k,从1 - n中选择k个数字,对于任意的数字,对这k个数字取模,不论以什么样的顺序取模,最终结果都一样,求选择的方案数%998244353.

Solution

很明显,如果不论以任何方式取模使得结果一样,则k个数中(从小到大排列),第一个数必须能整除后面的所有数。
那么只要枚举第一个数,然后从可以整除它的数字里面选k - 1个即可。
即为C(n / i - 1,k - 1)的和。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int SZ = 600000 + 10;
const ll MOD = 998244353; 
ll n,m;
ll JC[SZ];
 
inline ll pow_mod(ll a,ll b)
{
	ll r = 1;
	while(b)
	{
		if(b & 1) r = (r * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return r;
}
 
inline ll C(ll n,ll m)
{
	if(m > n) return 0;
	return ((JC[n] * pow_mod(JC[m],MOD - 2)) % MOD * pow_mod(JC[n - m],MOD - 2) % MOD);
}
/*
inline ll Lucas(ll n,ll m)
{
	if(!m) return 1;
	return C(n % p,m % p) * Lucas(n / p, m / p) % p;
}
*/
inline void get_JC()
{
	JC[0] = 1;
	for(int i = 1;i <= n;i ++) JC[i] = (JC[i - 1] * i) % MOD;
}
 
int main()
{
	scanf("%lld%lld",&n,&m);
	get_JC();
	ll ans = 0;
	for(int i = 1;i <= n;i ++)
	{
		if(n / i < m) continue;
		ans = (ans + C(n / i - 1,m - 1)) % MOD;
	}
	printf("%lld\n",ans);
}

2020.5.29

"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值