比赛链接:

https://codeforces.com/contest/1321

C. Remove Adjacent

题目大意:

给定一个字符串,当相邻的两个字符之间差值小于 1 的时候,可以删除他们中的任何一个,问最多能删除多少个字符。

思路:

最优的策略肯定是删除最大的先,所以从大到小枚举每一个字符,判断每一个字符能不能删除,能删除就删掉,然后从头开始重新判断。

代码:

#include <bits/stdc++.h>
using namespace std;
int n;
string s;
int main(){
	cin >> n >> s;
	for (char ch = 'z'; ch >= 'a'; ch -- ){
		for (int i = 0; i < s.size(); i ++ ){
			if (ch == s[i]){
				if (i > 0 && abs(s[i] - s[i - 1]) == 1){
					s.erase(s.begin() + i);
					i = -1;
				}
				else if (i < n - 1 && abs(s[i] - s[i + 1]) == 1){
					s.erase(s.begin() + i);
					i = -1;
				}
			}
		}
	}
	cout << n - s.size() << "\n";
	return 0;
}

D. Navigation System

题目大意:

给定一张有向图,图上任意两点之间保证可以到达,现在从 \(s\)\(t\),导航系统会给定一条最短路径,如果不按这个最短路径走,那么导航系统会重新规划最优的路径。现在已知从 \(s\)\(t\) 的一个路径,问导航系统最少和最多重新规划几次路线。

思路:

首先通过 \(bfs\) 求出每个点到终点的最短路径,将边的方向反一下去 \(bfs\) 就行。
当到的下一个点的距离大于当前点 - 1 时,说明不是最短路径,那么一定要重新规划路线。
当到的下一个点的距离等于当前点 - 1 时,如果有好几条最短路径,可以重新规划路径。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, k;
vector <int> g[N], G[N], p(N), d(N);
void bfs (){
	queue <int> q;
	q.push(p[k]);
	while (q.size()){
		int u = q.front();
		q.pop();
		for (auto v : g[u]){
			if (v == p[k]) continue;
			if (d[v]) continue;
			d[v] = d[u] + 1;
			q.push(v);
		}
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; i ++ ){
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		g[v].push_back(u);
	}
	cin >> k;
	for (int i = 1; i <= k; i ++ ){
		cin >> p[i];
	}
	bfs();
	int mn = 0, mx = 0;
	for (int i = 1; i < k; i ++ ){
		if (d[p[i + 1]] > d[p[i]] - 1){
			mn ++ ;
			mx ++ ;
		}
		else {
			int ok = 0;
			for (auto j : G[p[i]]){
				if (d[j] == d[p[i]] - 1 && j != p[i + 1]){
					ok = 1;
					break;
				}
			}
			mx += ok;
		}
	}
	cout << mn << " " << mx << "\n";
	return 0;
}

E. World of Darkraft: Battle for Azathoth

题意:

给定 \(n\) 件武器和 \(m\) 件防具,每件武器有一个攻击值和费用,每件防具有一个防御值和费用。
选择一个武器和一个防具去打 \(p\) 个怪兽,每个怪兽有防御值、攻击值和奖励,当武器的攻击值大于怪兽防御力且防具防御值大于怪兽攻击值时,可以打败这个怪兽并获得奖励。
问最多能获得多少钱(即打败怪兽获得的奖励 - 武器和防具的花费)。

思路:

可以先对武器按攻击值从小到大排序,怪兽按照防御值从小到大排序。
从小到大选择武器,可以打的怪兽一定是越来越多的,这样子就实现了攻击值满足的条件。
对于防御值,可以按照防御值大小建立线段树,下标为防御值,节点的值为获得的最大花费。
如果某个防御值对应的防具存在,那么它能获得的钱就是 -防具的花费,如果不存在,那么它获得的钱就是负无穷。
双指针枚举武器和怪兽,设打赢的怪兽的攻击值 \(a\),那么所有防御值大于 \(a\) 的防具都能够获得打赢这个怪兽的奖励。
每次枚举一个武器,计算获得的最大奖励 - 武器的花费,取一个最大值就是答案。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL N = 1e6 + 10, INF = 1e18 + 10;
LL n, m, p, w[N];
struct Node{
	LL x, y, z;
}a[N], d[N], mon[N];
bool cmp(Node a, Node b){
	return a.x < b.x;
}
struct segt{
	LL l, r, mx, add;
}tr[N * 4];
void pushup(LL u){
	tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);
}
void pushdown(LL u){
	auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
	left.add += root.add;
	right.add += root.add;
	left.mx += root.add;
	right.mx += root.add;
	root.add = 0;
}
void build(LL u, LL l, LL r){
	if (l == r){
		if (w[r]) tr[u] = {l, r, -w[r], 0};
		else tr[u] = {l, r, -INF, 0};
		return;
	}
	tr[u] = {l, r, -INF, 0};
	LL mid = l + r >> 1;
	build(u << 1, l, mid);
	build(u << 1 | 1, mid + 1, r);
	pushup(u);
}
void update(LL u, LL l, LL r, LL k){
	if (tr[u].l >= l && tr[u].r <= r){
		tr[u].mx += k;
		tr[u].add += k;
	}
	else{
		pushdown(u);
		LL mid = tr[u].l + tr[u].r >> 1;
		if (l <= mid) update(u << 1, l, r, k);
		if (r > mid) update(u << 1 | 1, l, r, k);
		pushup(u);
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n >> m >> p;
	for (int i = 0; i < n; i ++ )
		cin >> a[i].x >> a[i].y;
	for (int i = 0; i < m; i ++ ){
		cin >> d[i].x >> d[i].y;
		if (w[d[i].x]) w[d[i].x] = min(w[d[i].x], d[i].y);
		else w[d[i].x] = d[i].y;
	}
	for (int i = 0; i < p; i ++ )
		cin >> mon[i].x >> mon[i].y >> mon[i].z;
	sort(a, a + n, cmp);
	sort(mon, mon + p, cmp);
	build(1, 1, N - 10);
	LL ans = -INF;
	for (int i = 0, j = 0; i < n; i ++ ){
		while (j < p && mon[j].x < a[i].x){
			if (mon[j].y + 1 <= N - 10) update(1, mon[j].y + 1, N - 10, mon[j].z);  //要加一个判断,否则 wa 16
			j ++ ;
		}
		ans = max(ans, tr[1].mx - a[i].y);
	}
	cout << ans << "\n";
	return 0;
}
posted on 2022-05-17 12:37  Hamine  阅读(28)  评论(0编辑  收藏  举报