2022牛客寒假算法基础集训营2

本文介绍了几个算法问题,包括‘小沙的炉石’中的二分搜索解决斩杀问题,‘小沙的魔法’中利用贪心和并查集找最少操作次数,‘小沙的长路’涉及欧拉图的最大路径,‘小沙的算数’用离散化处理算术表达式,‘小沙的身法’通过树上差分和LCA求解最小花费,以及‘小沙的数数’中异或和最大化的二进制解法。

A 小沙的炉石

题意:
给定n张进攻卡和m张回复卡,每次使用进攻卡会消耗一点法力值并造成一点基础伤害和累计的法术伤害,每次使用回复卡会回复一点法力值,每使用一张卡片后都会使累计的法术伤害+1。一开始,法力值只有一点,法力值无上限。给定血量x,回答是否可以“刚好斩杀”。
“刚好斩杀”:通过合理的使用卡牌方式,使血量恰好变为0。

涉及算法:二分,等差数列

观察到:
最少可使用1张攻击卡,最多可使用min(n,m + 1)张攻击卡。
当这局使用x张攻击卡时:
伤害最大化:先把所有的回复卡打完,再尽可能的打出最多的攻击卡。
伤害最小化:先打一张攻击卡,再打一张回复卡,不断重复,直到无法打出攻击卡。

很容易可以得出,最小值到最大值这中间都是可以取到的值

二分如下:

bool binary_search(ll x) {
   
   
	ll l = 1, r = min(n, m + 1) + 1;
	bool f = 0;
	while (l < r) {
   
   
		ll mid = l + r >> 1;
		if (x >= mid * mid && x <= mid * m + mid * (mid + 1) / 2) {
   
   
			f = 1;
			break;
		}
		if (x < mid * mid) r = mid;
		else l = mid + 1;
	}
	return f;
}

B 小沙的魔法

题意:
你有n个点,和m条边,每个点初始值xi = 0。初始的时候图上没边,你可以进行两种操作:
1:在m条边里面选择一条没有被选过的边加入图中
2:将图中的一个极大连通子图中的每个点权值+1.
你需要使得对于任意的i,都有xi = ai。
你可以最多可以执行min(5∗n,m)次操作1。请问你最少进行多少次操作2。
给定边可能出现重边,自环的情况。

极大连通子图:

1.连通图只有一个极大连通子图,就是它本身。(是唯一的)
2.非连通图有多个极大连通子图。(非连通图的极大连通子图叫做连通分量,每个分量都是一个连通图)
3.称为极大是因为如果此时加入任何一个不在图的点集中的点都会导致它不再连通。

涉及算法:图的遍历,并查集,贪心

首先,对所有xi,去重并从大到小排序,从大到小遍历每个xi,将所有值为xi的点都加入图中,再根据现有连通图以及下一个xi,进行一次求解,累积答案。

核心代码如下:

void add(int u, int v) {
   
   
	es[++cnt].to = v;
	es[cnt].next = head[u];
	head[u] = cnt;
}

void solve() {
   
   
	int n, m;
	cin >> n >> m;

	for (int i = 1; i <= n; i++) {
   
   
		cin >> a[i], b[i] = a[i], fa[i] = i;
	}

	for (int i = 1; i <= m; i++) {
   
   
		int x, y;
		cin >> x >> y;
		add(x, y);
		add(y, x);
	}

	sort(a + 1, a + n + 1);
	int Size = unique(a + 1, a + n + 1) - a - 1;

	for (int i = 1; i <= n; i++) {
   
   
		v[lower_bound(a + 1, a + Size + 1, b[i]) - a].push_back(i);
	}

	ll ans = 0, sum = 0;
	for (int i = Size; i >= 1; i--) {
   
   
		for (int j : v[i]) {
   
   
			sum++;
            // 链式前向星遍历图
			for (int k = head[j]; k; k = es[k].next) {
   
   
				int l = es[k].to;
				if (b[l] < b[j]) continue;
				int x = find(l)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值