2026团体程序设计天梯赛L1+L2题解

大三老登第三年参加天梯赛,今年的题目真的简单好多。下面是本人在赛场上的代码合集:

L1 – 1

print("Building the Future, One Line of Code at a Time.")

最简单的入门题目,使用Py更快的解决。

L1 – 2

题意为每年的天梯赛有 15 道题目告诉你比赛的年数让你算题目总数,直接输出

15×n15 \times n

即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n; cin >> n;
	cout << n * 15;
	return 0;
}

L1 – 3

题目给出两个年份A和B,B – A 代表年龄让你判断:

  • 如果该寿命超过了人类最长寿命,在第二行中输出 jiu ting tu ran de...
  • 如果该寿命不是正数,输出 hai sheng ma?
  • 如果寿命在正常范围内,输出 nin tai cong ming le!

简单分支结构判断一下即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int a, b; cin >> a >> b;
	cout << b - a << endl;
	if(b - a <= 0) cout << "hai sheng ma?";
	else if(b - a > 250) cout << "jiu ting tu ran de...";
	else cout << "nin tai cong ming le!";
	return 0;
}

L1 – 4

给出所有参赛学生所属高校的评级分,统计高校评级分数小于1700的学生总人数。

简单循环加判断即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n; cin >> n;
	int cnt = 0;
	while(n --){
		int t; cin >> t;
		if(t < 1700) cnt ++;
	}
	cout << cnt;
	return 0;
}

L1 – 5

给出多个序号和是否被骂,寻找这些序号里仅仅被骂的人的数量。

使用map来存储状态,因为map是有序的可以顺便解决顺序输出的问题。

当且仅当map键值对中的值为0的时候更新(如果状态为0则不变,状态为1可以被记录),最后只需要找到状态为0的键即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n; cin >> n;
	map<int,bool> mp;
	for(int i = 0;i < n;i ++){
		int id, f; cin >> id >> f;
		if(mp[id] == 0) mp[id] = f;
	}
	int f = 0;
	for(auto [k,v] : mp)
		if(v == 0){
			if(f == 0) cout << k, f = 1;
			else cout << ' ' << k;
		} 
	if(f == 0) cout << "NONE";
	return 0;
}

L1 – 6

给出11行字符串,以m的数量来表达数字0-9。

使用getline和string直接秒。

#include<bits/stdc++.h>
using namespace std;

int main(){
	for(int i =0 ;i < 11;i ++){
		string s; getline(cin,s);
		cout << s.size();
	}
	return 0;
}

L1 – 7

给出n个值,找出最大值、最小值、平均值,并且标出超过平均值2倍的值对应的下标。

最大最小值直接调用函数或者写个循环,然后求和算平均值。算完后再次遍历数组即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n; cin >> n;
	vector<int> a(n);
	for(int i = 0;i < n;i ++) cin >> a[i];
	cout << *max_element(a.begin(),a.end()) << ' ' << *min_element(a.begin(),a.end()) << ' ';
	int avg = 0;
	for(int i = 0;i < n;i ++) avg += a[i];
	avg /= n; cout << avg << endl;
	int f = 0;
	for(int i = 0;i < n;i ++)
		if(a[i] > 2 * avg){
			if(f == 0) cout << i + 1, f = 1;
			else cout << ' ' << i + 1;
		}
	if(f == 0) cout << "Normal";
	return 0;
}

L1 – 8

给定一个字符串,对其进行如下操作:

  1. 查找指定字符串 s1​ 前 13 次出现的位置;
  2. 在指定位置 p 插入一个指定字符串 s2​的第 1 个字符;
  3. 将某一段连续的字符串翻转。

对于第一种操作可以使用类似于2024年猫娘题目的写法,使用find函数后将第一个字符直接替换成#然后进行下一次find即可。

对于第二种操作直接使用string的insert函数即可。

对于第三种操作直接使用reverse函数即可。

#include<bits/stdc++.h>
using namespace std;
string s;

void ch1(){
	string mod, t = s; cin >> mod;
	for(int i = 0;i < 3;i ++){
		int idx = t.find(mod);
		if(i == 0 && idx != -1){
			cout << idx;
			t[idx] = '#';
		}
		else if(i == 0 && idx == -1){
			cout << -1; break;
		}
		else if(i != 0 && idx != -1) {
			cout << ' ' << idx;
			t[idx] = '#';
		}
		else if(i != 0 && idx == -1) break;
	}
	cout << endl;
}

void ch2(){
	string mod;
	int idx;
	cin >> idx >> mod;
	s.insert(idx,mod);
	cout << s << endl;
}

void ch3(){
	int l, r; cin >> l >> r;
	reverse(s.begin() + l, s.begin() + r + 1);
	cout << s << endl;
}

int main(){
	int n; cin >> n >> s;
	while(n --){
		int op; cin >> op;
		if(op == 1) ch1();
		else if(op == 2) ch2();
		else ch3();
	}
	return 0;
}

L2 – 1

给定一个数组和阈值T如果数组的值小于等于T则输出其在原数组中对应的下标序号,将未输出下标的数组成一个新的数组,计算新的T重复执行这个操作直到新数组为空。

简单使用模拟即可,开辟一个数组zu来存放未输出的数和其对应的下标序号,注意顺序是逆序的。然后写个死循环直到zu数组生成为空结束即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n, t; cin >> n >> t;
	vector<int> a(n), ans;
	for(int i = 0;i < n;i ++) cin >> a[i];
	vector<pair<int,int>> zu;
	for(int i = 0;i < n;i ++)
		if(a[i] <= t) ans.push_back(i + 1);
		else zu.push_back({a[i],i + 1});
	reverse(zu.begin(),zu.end());
	while(zu.size()){
		int newt = 0;
		vector<pair<int,int>> t;
		for(int i = 0;i < zu.size();i ++) newt += zu[i].first;
		newt /= (int)zu.size();
		for(int i = 0;i < zu.size();i ++)
			if(zu[i].first <= newt) ans.push_back(zu[i].second);
			else t.push_back(zu[i]);
		reverse(t.begin(),t.end());
		zu = t;
	}
	for(int i = 0;i < ans.size();i ++)
		if(i == 0) cout << ans[i];
		else cout << ' ' << ans[i];
	return 0;
}

L2 – 2

给定一个数组,输出其最大数在数组中的下标序号。并进行m次查询,寻找每次大于x的第一个数在数组的下标,如果不存在输出0。

需求1可以直接计算最大值然后遍历输出即可,需求2可以将数组排序随后使用upper_bound二分寻找大于x的第一个数,随后判断一下是否存在即可。使用map来记录每个数第一次出现的下标序号即可。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n; cin >> n;
	vector<int> a(n);
	map<int,int> mp;
	for(int i = 0;i < n;i ++){
		cin >> a[i];
		if(mp[a[i]] == 0) mp[a[i]] = i + 1;
	}
	int mx = *max_element(a.begin(),a.end()), f = 0;
	for(int i = 0;i < a.size();i ++)
		if(a[i] == mx)
			if(f == 0) cout << i + 1, f = 1;
			else cout << ' ' << i + 1;
	cout << endl;
	sort(a.begin(),a.end());
	int m; cin >> m;
	while(m --){
		int x; cin >> x;
		int idx = upper_bound(a.begin(),a.end(),x) - a.begin();
		if(idx == n) cout << 0 << endl;
		else cout << mp[a[idx]] << endl;
	}
	return 0;
}

L2 – 3

给定一棵树,求从跟节点开始到达所有叶子节点的路径中权值的最小值最大为多少并输出该路径的叶子节点序号(从小到大)。

直接使用dfs遍历即可,到达根节点时更新答案和叶子节点数组即可。

#include<bits/stdc++.h>
using namespace std;
int n, mxans = -1;
vector<int> ans;
vector<pair<int,int>> g[100010];
void dfs(int u,int mx){
	if(g[u].empty()){
		if(mxans < mx){
			mxans = mx;
			ans.clear();
			ans.push_back(u);
		}
		else if(mxans == mx) ans.push_back(u);
	}
	for(auto [v,val] : g[u])
		dfs(v,min(mx,val));
}

int main(){
	cin >> n;
	for(int u = 1;u < n;u ++){
		int v, val; cin >> v >> val;
		g[v].push_back({u, val});
	}
	dfs(0,1e9);
	cout << mxans << endl;
	sort(ans.begin(),ans.end());
	for(int i = 0;i < ans.size();i ++)
		if(i == 0) cout << ans[i];
		else cout << ' ' << ans[i];
	return 0;
}

L2 – 4

对每个给定起点,在有向图中每次贪心选择“概率最大、若并列则编号最小且未访问过”的下一节点,不断前进直到无路可走,并输出整条路径。

简单来说对每一个节点的子节点按概率排序,概率相同的序号小的优先。

使用广度优先遍历从每次询问的起始节点开始,每次找到未在该链中出现过的最大概率的节点直到没有。

#include<bits/stdc++.h>
using namespace std;
int n, m;
vector<pair<int,int>> g[100010];

bool cmp(pair<int,int> a, pair<int,int> b){
	return a.second > b.second || (a.second == b.second) && (a.first < b.first);
}

int main(){
	cin >> n >> m;
	for(int i = 0;i < m;i ++){
		int id1, id2, p; cin >> id1 >> id2 >> p;
		g[id1].push_back({id2,p});
	}
	for(int i = 1;i <= n;i ++) sort(g[i].begin(),g[i].end(),cmp);
	int k; cin >> k;
	while(k --){
		int q; cin >> q;
		bool mp[10001] = {false};
		queue<int> qu;
		qu.push(q);
		mp[q] = true;
		cout << q;
		while(!qu.empty()){
			int u = qu.front();
			qu.pop();
			for(int i = 0;i < g[u].size();i ++)
				if(mp[g[u][i].first] == false){
					cout << "->" << g[u][i].first;
					mp[g[u][i].first] = true;
					qu.push(g[u][i].first);
					break;
				}
		}
		cout << endl;
	}
	return 0;
}

此处mp不能使用map否则会超时,该做法不是最优解法但是胜在好写。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注