Codeforces Round 918 (Div. 4) 补题AK

比赛链接
E题用umap被hack了,F有个简单知识点没学,离青又远了

A 模拟

思路 3个数找只出现一次的,直接上异或
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;

int a, b, c;
void solve() {
	cin >> a >> b >> c;

	cout << (a ^ b ^ c) << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}

B 模拟

思路 找3个字符中没出现的那个,直接上哈希+枚举
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;

char s[5][5];
void solve() {
	forn(i, 1, 3) forn(j, 1, 3) cin >> s[i][j];

	forn(i, 1, 3) {
		umap<char, int> mp;
		forn(j, 1, 3) mp[s[i][j]]++;
		forn(j, 'A', 'C') {
			if (mp[j] == 0) {
				cout << (char) j << endl;
				return;
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}

C 模拟

思路 就是判断是不是平方数,语法题没什么好说的
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;

ll n;
ll a[N];
double sum;
void solve() {
	cin >> n;
	sum = 0;
	forn(i, 1, n) cin >> a[i], sum += a[i];

	ll x = (ll) sqrt(sum);
	if (x * x == sum) cy;
	else cn;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}

D 思维 模拟

思路 首先把字符全部预处理成c和v

发现如果是cvc和cv第一个字符都是c不好区分

如果翻转一下,cvc和vc就很好区分了,直接遍历一遍,再把得到的答案翻转即可

代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;

int n;
char s[N], a[N];
void solve() {
	cin >> n;
	forn(i, 1, n) cin >> s[i];

	forn(i, 1, n) {
		if (s[i] == 'a' || s[i] == 'e') a[i] = 'v';
		else
			a[i] = 'c';
	}

	reverse(a + 1, a + n + 1);
	reverse(s + 1, s + n + 1);
	vector<char> ans;

	int l = 1;
	while (l <= n) {
		if (a[l] == 'c') {
			ans.push_back('.');
			forn(i, l, l + 2) ans.push_back(s[i]);
			l += 3;
			continue;
		}
		if (a[l] == 'v') {
			ans.push_back('.');
			forn(i, l, l + 1) ans.push_back(s[i]);
			l += 2;
		}
	}
	reverse(ans.begin(), ans.end());
	ans.pop_back();
	for (auto i : ans) cout << i;
	cout << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}

E 思维 前缀和

思路

image

直接求一遍这个式子的前缀和,如果两个前缀和相等,那么它们之间的子数组的和为 0

可以用哈希来实现(注意用map,umap会被卡)

代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;

ll n;
ll a[N];
ll sum[N];
void solve() {
	cin >> n;
	forn(i, 1, n) cin >> a[i];

	int ok = 0;
	map<ll, ll> mp;
	forn(i, 1, n) {
		if (i & 1) sum[i] = sum[i - 1] + a[i];
		else sum[i] = sum[i - 1] - a[i];	
		if (sum[i] == 0 || mp[sum[i]]) ok = 1;
		mp[sum[i]]++;
	}

	if (ok) cy;
	else cn;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}

F 离散化 树状数组/线段树 思维

思路

image

按左端点排序,再查看每个人右端点经过几条之前条线段,可以转化为区间问题

对于每个人,答案累加上右端点上的值,之后再将区间整体加1,可以使用树状数组+离散化实现

代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 4e5 + 5;
int T;

ll n;
ll t[N];
ll lowbit(ll x) {
	return x & -x;
}
void add(ll x, ll k) {
	while (x <= 2 * n) {
		t[x] += k;
		x += lowbit(x);
	}
}
ll sum(ll x) {
	ll s = 0;
	while (x > 0) {
		s += t[x];
		x -= lowbit(x);
	}
	return s;
}
void add(int l, int r, int k) {
	add(l, k), add(r + 1, -k);
}

struct node {
	ll a, b;
} s[N], ss[N];
vector<ll> v;
bool cmp(node x, node y) {
	return x.a < y.a;
}
void solve() {
	cin >> n;
	forn(i, 1, n) cin >> s[i].a >> s[i].b;

	v.clear();
	forn(i, 1, n) {
		v.push_back(s[i].a);
		v.push_back(s[i].b);
	}
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
	forn(i, 1, n) {
		s[i].a = lower_bound(v.begin(), v.end(), s[i].a) - v.begin() + 1;
		s[i].b = lower_bound(v.begin(), v.end(), s[i].b) - v.begin() + 1;
	}
	memset(t, 0, sizeof t);
	sort(s + 1, s + n + 1, cmp);
	ll ans = 0;
	forn(i, 1, n) {
		ans += sum(s[i].b);
		add(s[i].a, s[i].b, 1);
	}

	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}

G 最短路 思维

思路

image
感觉有种DP的感觉

代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const ll inf = 1e18;
const int N = 1e3 + 5;
int T;

int n, m;
struct edge {
	ll to, w;
};
struct node {
	ll dis, id, cost;
	bool operator<(const node &x) const {
		return dis > x.dis;
	}
};
vector<edge> g[N];
ll s[N];
ll dist[N][N];
bool vis[N][N];
void dijkstra() {
	memset(vis, 0, sizeof vis);
	forn(i, 1, n) forn(j, 1, 1000) dist[i][j] = inf;
	dist[1][s[1]] = 0;
	priority_queue<node> q;
	q.push({0, 1, s[1]});
	while (!q.empty()) {
		node now = q.top();
		q.pop();
		ll u = now.id, cost = now.cost;
		if (vis[u][cost] || dist[u][cost] == inf) continue;
		vis[u][cost] = 1;
		for (auto i : g[u]) {
			int v = i.to, w = i.w;
			ll c = min(s[v], cost);
			if (dist[v][c] > dist[u][cost] + w * cost) {
				dist[v][c] = dist[u][cost] + w * cost;
				q.push({dist[v][c], v, c});
			}
		}
	}
}
void solve() {
	cin >> n >> m;
	forn(i, 1, n) g[i].clear();
	forn(i, 1, m) {
		ll u, v, w;
		cin >> u >> v >> w;
		g[u].push_back({v, w});
		g[v].push_back({u, w});
	}
	forn(i, 1, n) cin >> s[i];

	dijkstra();

	ll ans = inf;
	forn(i, 1, 1000) ans = min(ans, dist[n][i]);
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	// T=1;

	while (T--) solve();
	return 0;
}
posted @ 2023-12-30 14:19  史上最速败犬  阅读(20)  评论(0)    收藏  举报