2025寒假天梯赛训练3

2025寒假天梯赛训练3

L1-1 今天我要赢

思路

代码

I'm gonna win! Today!
2022-04-23

L1-2 种钻石

思路

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int N,v;
	cin >> N >> v;

	cout << N / v << "\n";	

	return 0;
}

L1-3 谁能进图书馆

思路

模拟。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int a, b, x, y;
	cin >> a >> b >> x >> y;

	if (x >= a && y >= a) {
		cout << x << "-Y " << y << "-Y\n";
		cout << "huan ying ru guan\n";
	} else if (x < a && y < a) {
		cout << x << "-N " << y << "-N\n";
		cout << "zhang da zai lai ba\n";
	} else if (x >= b && y < a) {
		cout << x << "-Y " << y << "-Y\n";
		cout << "qing 1 zhao gu hao 2\n";
	} else if (x < a && y >= b) {
		cout << x << "-Y " << y << "-Y\n";
		cout << "qing 2 zhao gu hao 1\n";
	} else {
		if (x >= a) {
			cout << x << "-Y " << y << "-N\n";
		} else {
			cout << x << "-N " << y << "-Y\n";
		}
		cout << "12"[y >= a] << ": huan ying ru guan\n";
	}

	return 0;
}

L1-4 拯救外星人

思路

计算阶乘。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int a, b;
	cin >> a >> b;
	a += b;

	i64 ans = 1;
	while (a--) {
		ans *= (a + 1);
	}

	cout << ans << "\n";

	return 0;
}

L1-5 试试手气

思路

按题意模拟。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int a[6] {}, c[7][7] {} ;
	for (int i = 1; i <= 6; i ++) {
		cin >> a[i];
		c[i][a[i]] = 1;
	}

	int n;
	cin >> n;

	n--;
	while (n--) {
		for (int i = 1; i <= 6; i ++) {
			for (int j = 6; j >= 1; j --) {
				if (c[i][j]) continue;
				c[i][j] = 1;
				break;
			}
		}
	}

	for (int i = 1; i <= 6; i ++) {
		for (int j = 6; j >= 1; j --) {
			if (c[i][j]) continue;
			cout << j << " \n"[i == 6];
			break;
		}
	}

	return 0;
}

L1-6 斯德哥尔摩火车上的题

思路

按题意模拟。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	string s[2];
	cin >> s[0] >> s[1];

	string ans[2];
	for (int i : {0, 1}) {
		for (int j = 1; j < s[i].size(); j ++) {
			if (s[i][j] % 2 == s[i][j - 1] % 2) {
				ans[i] += max(s[i][j], s[i][j - 1]);
			}
		}
	}

	if (ans[0] == ans[1]) {
		cout << ans[0] << "\n";
	} else {
		cout << ans[0] << "\n" << ans[1] << "\n";
	}

	return 0;
}

L1-7 机工士姆斯塔迪奥

思路

总安全格子数等于总格子数减去被攻击的行列覆盖的格子,并消除重复计算。设 \(R\) 为被攻击的行数,\(C\) 为被攻击的列数,则被覆盖的格子数为 \(m \times R + n \times C - R \times C\)(行覆盖 \(m \times R\),列覆盖 \(n \times C\),交点重复计算 \(R \times C\))。最终答案可表示为:

\[ans = n \times m - (m \times R + n \times C - R \times C) \]

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, q;
	cin >> n >> m >> q;

	set<int> s[2];
	while (q--) {
		int c, t;
		cin >> c >> t;
		s[c].insert(t);
	}

	int ans = n * m;
	ans -= m * s[0].size() + n * s[1].size() - s[0].size() * s[1].size();

	cout << ans << "\n";

	return 0;
}

L1-8 静静的推荐

思路

考察排序。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, k, s;
	cin >> n >> k >> s;

	vector has(300, vector<int>());
	while (n--) {
		int a, b;
		cin >> a >> b;
		if (a < 175) continue;
		has[a].emplace_back(b);
	}

	int ans = 0;
	for (int i = 175; i <= 290; i ++) {
		sort(has[i].begin(), has[i].end(), greater<>());
		int t = k;
		for (auto j : has[i]) {
			if (j >= s) {
				ans ++;
			} else if (t-- > 0) {
				ans += 1;
			}
		}
	}

	cout << ans << "\n";

	return 0;
}

L2-1 插松枝

思路

该问题模拟工人制作松枝的过程,使用栈模拟小盒子,动态维护当前松枝的状态。每次从推送器或小盒子中取出松针,确保新松针不大于前一个松针。若小盒子满且无法继续,或推送器无松针,或松枝达到最大容量,则完成当前松枝并开始新的制作。

  1. 若小盒子顶部松针满足条件,则直接使用;否则从推送器取松针。
  2. 若推送器松针不满足条件且小盒子未满,则将其压入小盒子;否则完成当前松枝。
  3. 重复上述过程,直到所有松针用完。最终输出每根松枝的松针序列。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	vector<int> a(n);
	for (auto &i : a) {
		cin >> i;
	}

	int N = n;
	stack<int> st;
	vector<vector<int>> has;
	vector<int> t;

	int idx = -1;
	while (n) {
		bool ok = 0;
		while (st.size() && (t.empty() || st.top() <= t.back())) {
			t.push_back(st.top());
			st.pop();
			if (t.size() == k) {
				has.push_back(t);
				n -= t.size();
				t.clear();
				ok = 1;
				break;
			}
		}
		if (ok) continue;
		while (idx + 1 < N) {
			if (t.empty() || a[idx + 1] <= t.back()) {
				t.push_back(a[idx + 1]);
				idx ++;
			} else {
				if (st.size() == m) {
					has.push_back(t);
					n -= t.size();
					t.clear();
					ok = 1;
					break;
				}
				st.push(a[idx + 1]);
				idx ++;
			}
			if (t.size() == k) {
				has.push_back(t);
				n -= t.size();
				t.clear();
				ok = 1;
				break;
			}
		}
		if (ok) continue;
		has.push_back(t);
		n -= t.size();
		t.clear();
	}

	for (auto x : has) {
		for (int i = 0; i < x.size(); i ++) {
			cout << x[i] << " \n"[i == x.size() - 1];
		}
	}

	return 0;
}

L2-2 老板的作息表

思路

按题意模拟,注意最好是把秒与秒之间分开,我这里是引入\(0.5\) 乘了\(10\) 倍,比如 \(00:00:02\sim 00:00:03\) 是可以分成两个时间段。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n;
	cin >> n;

	int ed = 24 * 60 * 60;
	vector need(ed, 0), ck(ed * 10, 0);
	while (n--) {
		int h1, m1, s1, h2, m2, s2;
		char c;
		cin >> h1 >> c >> m1 >> c >> s1 >> c;
		cin >> h2 >> c >> m2 >> c >> s2;

		int t1 = h1 * 3600 + m1 * 60 + s1;
		int t2 = h2 * 3600 + m2 * 60 + s2;
		for (int i = t1 + 1; i < t2; i ++) {
			need[i] = 1;
		}
		for (int i = t1; i < t2; i ++) {
			ck[i * 10 + 5] = 1;
		}
	}

	auto pt = [](int x)->void{
		printf("%02d:", x / 3600);
		x %= 3600;
		printf("%02d:", x / 60);
		x %= 60;
		printf("%02d", x);
	};

	for (int i = 0; i < ed; i ++) {
		int a = i;
		while (a + 1 < ed && !need[a + 1]) {
			a ++;
			if (ck[a * 10 + 5]) break;
		}
		if (ck[i * 10 + 5] || a - i < 1) continue;
		pt(i);
		printf(" - ");
		pt(a);
		printf("\n");
		i = a;
	}

	return 0;
}

L2-3 龙龙送外卖

思路

最优路径即是最长的那条路放在最后去走,那么我们对于所有要走的点,先记录他们的路程长度两倍,即假设每次送完外卖都回去,对于新增的点,去找最近的被加入的点即可,沿路计算的路径的时候维护最大的深度。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, q;
	cin >> n >> q;

	int rt = -1;
	vector<int> fa(n + 1), d(n + 1);
	for (int i = 1; i <= n; i ++) {
		int x;
		cin >> x;
		if (x == -1) {
			rt = i;
		} else {
			fa[i] = x;
		}
	}

	int Max = 0;
	set<int> has;
	auto dfs = [&](auto && self, int u, int dis)->int{
		if (has.count(u)) {
			Max = max(Max, d[u] + dis);
			return 2 * dis;
		}
		int res = self(self, fa[u], dis + 1);
		d[u] = d[fa[u]] + 1;
		has.insert(u);
		return res;
	};

	has.insert(rt);

	int ans = 0;
	while (q--) {
		int v;
		cin >> v;
		ans += dfs(dfs, v, 0);
		cout << ans - Max << "\n";
	}

	return 0;
}

L2-4 大众情人

思路

\(Floyd\) 将两两之间的最短距离计算出来,剩下就找异性缘最大的即可。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n;
	cin >> n;

	constexpr int inf = INT_MAX / 2;
	vector<int> fw(n + 1);
	vector d(n + 1, vector<int>(n + 1, inf));

	for (int i = 1; i <= n; i ++) {
		char c;
		int k;
		cin >> c >> k;

		fw[i] = c == 'F';
		while (k--) {
			int x, dis;
			cin >> x >> c >> dis;
			d[i][x] = dis;
		}
		d[i][i] = 0;
	}

	for (int k = 1; k <= n; k ++) {
		for (int i = 1; i <= n; i ++) {
			for (int j = 1; j <= n; j ++) {
				if (i != j) {
					d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
				}
			}
		}
	}

	vector<int> v(n + 1, -inf);
	for (int i = 1; i <= n; i ++) {
		for (int j = i + 1; j <= n; j ++) {
			if (fw[i] ^ fw[j]) {
				v[i] = max(v[i], d[j][i]);
				v[j] = max(v[j], d[i][j]);
			}
		}
	}

	int Min[2] {inf, inf};
	vector<int> ans[2];
	for (int i = 1; i <= n; i ++) {
		int t = fw[i];
		if (Min[t] > v[i]) {
			ans[t].clear();
			Min[t] = v[i];
			ans[t].emplace_back(i);
		} else if (v[i] == Min[t]) {
			ans[t].emplace_back(i);
		}
	}

	for (int i : {1, 0}) {
		for (int j = 0; j < ans[i].size(); j ++) {
			cout << ans[i][j] << " \n"[j == ans[i].size() - 1];
		}
	}

	return 0;
}

思路

代码


posted @ 2025-02-09 19:25  Ke_scholar  阅读(34)  评论(0)    收藏  举报