#727 div2 A 思维(细节 B 前缀和 C 思维 D 双指针

本文讨论了两个编程题目:竞赛参赛者分组和稳定分组问题。第一部分涉及计算在限制条件下的组合计数,而第二部分则是关于根据学生间差值分组的最优化策略。通过排序和插入操作最小化分组数,适合竞赛管理和团队组建场景。
摘要由CSDN通过智能技术生成

A. Contest Start
tmp 的大小,实际就是第一个人结束之后,后边有多少人在进行中,但是考虑实际,tmp是不可能>=n的,这种情况实际就是第一个人结束后,后边n-1个人都在进行;另外就是 tmp < n 的情况
第一个情况可能被忽略导致错误

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 2e6 + 10;

ll x, t, n, m, k;
int main ()
{
	cin >> t;
	while(t--)
	{
		scanf("%lld %lld %lld", &n, &x, &k);
		ll tmp = (ll)k / x, ans = 0;
		if(n <= tmp){
			printf("%lld\n", n * (n - 1) / 2);
		}
		else {
			ans += (n - tmp) * tmp;
			ans += (ll)(tmp - 1) * (ll)tmp / 2;
			printf("%lld\n", ans);
		}
	
	}
   return 0;
}

B. Love Song
就一个前缀和 没别的

C. Stable Groups
题意:给n个学生分组,一组中相邻的学生差值不大于x即为稳定的,最多可以插入k个任意取值的学生,求最少的可以分成的组数
思路:
根据例子分组可以不连续,就sort一遍,存下来每个差值大于x的临界点需要插入的学生个数,然后sort一下这个数组,从需要最少的开始弥补这个缺点,最小化分组数

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 2e5 + 10;

ll x, t, n, m, k;
ll a[N];
ll g[N], cnt;
int main ()
{
	scanf("%lld %lld %lld", &n, &k, &x);
	for(int i = 1; i <= n; ++i)	scanf("%lld", &a[i]);
	sort(a+1,a+1+n);
	for(int i = 2; i <= n; ++i)
	{
		ll tmp = abs(a[i] - a[i-1]);
		if(tmp > x)
			g[++cnt] = tmp%x==0?tmp/x-1:tmp/x;
	}
	sort(g+1,g+1+cnt);
	ll ans = 0;
	for(int i = 1; i <= cnt; ++i)
	{
		if(k - g[i] >= 0) ++ans, k -= g[i];
		else break;
	}
	//cout << cnt << " " << ans << endl;
	cout << cnt - ans + 1 << endl;
   return 0;
}


D. PriceFixed
题意:ai 是第 i 个物品需要购买的数量,bi 是第 i 个物品打折所需要的物品数(当前累计已买的所有物品数的总和),第 i 个物品超过 bi 的部分可以半价购买。读懂题意其实就发现只有 bi 比较小的才能半价购买
思路:对于易打折的产品,采取一元购的措施,当不满足打折要求时,购买难打折的产品来为其凑数量。
代码实现可以细细品
参考

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 2e5 + 9;
ll t, n, m;
struct node
{
	ll a, b;
}d[N];
bool cmp(node a, node b)
{
	return a.b < b.b;
}
int main()
{
	cin >> n;
	for(int i = 1; i <= n; ++i)	scanf("%lld %lld", &d[i].a, &d[i].b);
	sort(d+1,d+1+n,cmp);
	ll l = 1, r = n, ans = 0, cnt = 0;
	while(l <= r)
	{
		if(d[l].b <= cnt)
		{
			ans += d[l].a;
			cnt += d[l++].a;
		}
		else 
		{
			ll num = min(d[r].a, d[l].b - cnt);
			ans += num * 2;
			cnt += num;
			d[r].a -= num;
			if(!d[r].a) --r;
		}
	}
	cout << ans << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值