TOYOTA SYSTEMS Programming Contest 2024(AtCoder Beginner Contest 377) 补题记录(A-E)

AtCoder Beginner Contest 377

A - Rearranging ABC

字符串有ABC三个字母即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
	string s;
	cin >> s;
	map<char, int> mp;
	for (auto t : s) {
		mp[t] = 1;
	}
	if (mp['A'] == 1 && mp['B'] == 1 && mp['C'] == 1) cout << "Yes\n";
	else cout << "No\n";
}

B - Avoid Rook Attack

标记一下哪行哪列不可以放,然后暴力枚举

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
	char a[10][10];
	map<int, int> h, l;
	for (int i = 1; i <= 8; i++)
		for (int j = 1; j <= 8; j++) {
			cin >> a[i][j];
			if (a[i][j] == '#') h[i] = 1, l[j] = 1;
		}
	int cnt = 0;
	for (int i = 1; i <= 8; i++) {
		for (int j = 1; j <= 8; j++) {
			if (a[i][j] == '.') {
				if (h[i] == 0 && l[j] == 0) cnt++;
			}
		}
	}
	cout << cnt << '\n';
}

C - Avoid Knight Attack

\(set\)套一个\(pair\)将所有能吃的点和有马的点存入\(set\),能放的点就是剩下的点。

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
	int n, m;
	cin >> n >> m;
	set<pair<int, int>> se;
	int dx[10] = {-1, -2, -2, -1, 1, 2, 2, 1};
	int dy[10] = {-2, -1, 1, 2, 2, 1, -1, -2};
	while (m--) {
		int x, y;
		cin >> x >> y;
		se.insert({x, y});
		for (int i = 0; i < 8; i++) {
			if (x + dx[i] >= 1 && x + dx[i] <= n && y + dy[i] >= 1 && y + dy[i] <= n)
				se.insert({x + dx[i], y + dy[i]});
		}
	}
	cout << n*n - se.size() << '\n';
	
}

D - Many Segments 2

首先考虑加法不好做,于是我们选择减法减去所有不合法的区间,那么剩下的就是我们需要的答案。

通过模拟和思考发现我们可以枚举每一个位置 \(i\)查询离这个位置右侧最近的区间左边界\(r\),同时这个区间右边界\(l\)需要大于等于\(i\)此时可以删除(\(i\),\([r,m]\))这些区间组合。

为了实现我们的需求,我们可以对区间按照\(r\)排序,使用双指针查找合法可删除区间。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
struct node {
	int l, r;
} a[N];
bool cmp(node x, node y) {
	if (x.r != y.r) return x.r < y.r;
	return x.l < y.l;
}
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].l >> a[i].r;
	}
	sort(a + 1, a + 1 + n, cmp);
	int j = 1;
	int ans = m + m * (m - 1) / 2;
	for (int i = 1; i <= m; i++) {
		int x = i;
		while (a[j].l < x && j < n) j++;
		if (a[j].l < x) ans -= 0;
		else ans -= (m - a[j].r + 1);
	}
	cout << ans << '\n';
}

E - Permute K times 2