2023年团体程序设计天梯赛全国总决赛L1题解

酶和ATP 2023年04月23日 757次浏览

有幸 AK(全部满分通过) 了 L1,最终总分 187 分荣获国三,存一下赛时代码和部分做题思路留作纪念。
二阶还在补🐦

L1-1 最好的文档

签到

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;

void solve() {
	 cout << "Good code is its own best documentation." << endl;
}


signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
	}
}

L1-2 什么是机器学习

签到

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;

void solve() {
	int a, b;
    cin >> a >> b;
    int c = a + b;
    cout << c - 16 << endl;
    cout << c - 3 << endl;
    cout << c - 1 << endl;
    cout << c << endl;
}


signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
	}
}

L1-3 程序员买包子

签到 if-else

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;

int n, m, k;
string x;

void solve() {
	cin >> n >> x >> m >> k;
	if (k == n) {
		cout << "mei you mai " << x << " de";
	} else if (k == m) {
		cout << "kan dao le mai " << x << " de" << endl;
	} else {
		cout << "wang le zhao mai " << x << " de" << endl;
	}
}


signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
	}
}

L1-4 进化论

签到 if-else

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;



void solve() {
	int a, b, c;
	cin >> a >> b >> c;
	if (a * b == c) cout << "Lv Yan" << endl;
	else if (c == a + b) cout << "Tu Dou" << endl;
	else cout << "zhe du shi sha ya!" << endl;
}


signed main() {
	int T = 1;
	cin >> T;
	while(T--) {
		solve();
	}
}

L1-5 猜帽子游戏

模拟
定义两个bool类型变量看是否猜错(caicuo)和是否猜对(caidui),再判断一下即可。

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;

const int N = 110;
int a[N];

void solve() {
	int n;
	cin >> n;
	for (int i = 0;i < n;i ++) cin >> a[i];
	int tt;
	cin >> tt;
	while (tt--) {
		bool caicuo = false, caidui = false;
		for (int i = 0;i < n;i ++) {
			int x;
			cin >> x;
			if (x == 0) continue;
			if (x == a[i]) caidui = true;
			if (x != a[i]) caicuo = true;
		}
		if (caidui && !caicuo) {
			cout << "Da Jiang!!!" << endl;
		} else {
			cout << "Ai Ya" << endl;
		}
	}
}


signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
	}
}

L1-6 剪切粘贴

考查字符串函数运用的简单模拟

主要考察字符串函数 substr 和 find 的用法
假设s是一个字符串 abcdefg。
substr 后面可以接两个参数:
1⃣️s.substr(a) a是坐标(从0开始),切到最后。如 s.substr(2) = "cdefg"。2⃣️s.substr(a, length),第二个参数是长度,代表要切多少个字符。
find 后面接要查询的字符串,用的是暴力枚举法。
s.find("abc") 如果没找到返回 -1,否则返回 a (find内字符串第一个字母)的坐标(从0开始)。

在这个题目中,所给的操作区间是从1开始,所以我们先给字符串加一个空格,方便后面操作。

推荐先用“题干”(不是测试样例)中给的小样例

abcdefg 1
3 5
bf g

并在代码中多输出,进行调试。

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#include <string>
#define int long long
using namespace std;

string s;
int n;

void solve() {
	 cin >> s >> n;
	 s = " " + s;
	 for (int i = 0;i < n;i ++) {
	 	int a, b;
	 	cin >> a >> b;
	 	string cutted = s.substr(a, b - a + 1);
	 	// cout << cutted << endl;
	 	s = s.substr(0, a) + s.substr(b + 1);
	 	// cout << s << endl;
	 	
	 	string c, d;
	 	cin >> c >> d;
	 	int pos = s.find(c + d);
	 	if (pos == -1) s = s + cutted;
	 	else {
	 		// cout << pos << endl;
	 		//out << s.substr(0, pos + c.size()) << endl;
	 		s = s.substr(0, pos + c.size()) + cutted + s.substr(pos + c.size());
		}
		//for (int i = 1;i < s.size(); i++) cout << s[i];
		// cout << endl;
	 }
	 for (int i = 1;i < s.size(); i++) cout << s[i];
}
/*
abcdefg 1
3 5
bf g
*/

signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
	}
}

L1-7 分寝室

因数分解+暴力
L1的题目基本无需考虑时间复杂度,直接硬上就可以。

首先先把n0和n1的因数枚举出来,我把他作为作为房间个数来存,题干中说明不可以是一人一间,所以在枚举的时候要特判 因数==1 的情况。
然后暴力从因数中找即可。
(我define int longlong 所以 mmin 才那么奇怪

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;

int n0, n1, n;
vector<int> a, b;

void solve() {
	 cin >> n0 >> n1 >> n;
	 for (int i = 1;i <= n0 / i;i ++ ) {
	 	if (n0 % i == 0) {
	 		a.push_back(i);
 			if (i != 1 && i != n0 / i) a.push_back(n0 / i);
 		}
	 }	
	 for (int i = 1;i <= n1 / i;i ++ ) {
	 	if (n1 % i == 0) {
	 		b.push_back(i);
	 		if (i !=1 && i != n1 / i) b.push_back(n1 / i);
		 } 
	 }
	 int mmin = 0x3f3f3f3f3f3f3f3f, ansa = -1,ansb = -1;
	 for (int i = 0;i < a.size();i ++) {
	 	for (int j = 0;j < b.size();j ++) {
	 		if (a[i] + b[j] != n) continue;
	 		if (abs(n0 / a[i] - n1 / b[j]) < mmin) {
	 			mmin = abs(n0 / a[i] - n1 / b[j]);
	 			ansa = a[i],ansb = b[j];
			 }
		 }
	 }
	 if (mmin == 0x3f3f3f3f3f3f3f3f) cout << "No Solution";
	 else cout << ansa << ' ' << ansb << endl;
}


signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
        //cout << "No Solution";
	}
}

L1-8 谁管谁叫爹

模拟

注意一下细节把握即可,想清楚同时存在或者同时不存在这种情况怎么用代码实现。
涉及到一个数字的每一位有关的问题,建议用字符串读取方便快捷。

#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <queue>
#define int long long
using namespace std;

int n;

int cal(string s) {
	int res = 0;
	for (auto &x : s) {
		res += x - '0';
	}
	return res;
}

void solve() {
	 cin >> n;
	 for (int i = 1;i <= n;i ++) {
	 	 string a, b;
	 	 cin >> a >> b;
	 	 int na = stoi(a), nb = stoi(b);
	 	 int sa = cal(a),sb = cal(b);
	 	 bool fa = false, fb = false;
		 if (na % sb == 0) {
		 	fa = true;
		 }
		 if (nb % sa == 0) {
		 	fb = true;
		 } 
		 if (fa != fb) {
		 	if (fa) cout << "A" << endl;
		 	else cout << "B" << endl;
		 } else {
		 	if (na > nb) cout << "A" << endl;
		 	else cout << "B" << endl;
		 }
	 }
}


signed main() {
	int T = 1;
	// cin >> T;
	while(T--) {
		solve();
	}
}