【天梯赛训练记录】GPLT 团体程序设计天梯赛训练2

训练情况

赛后反思

差点被大模拟创死了,居然调出来了,后序遍历转层序遍历差点没做出来,最后几分钟极限过的,图论还需要加强

L1-1

签到题

点击查看代码
#include <bits/stdc++.h>

using namespace std;

int main(){
	cout<<"Talk is cheap. Show me the code.";
}

L1-2

签到题,体积是长x宽x高

点击查看代码
#include <bits/stdc++.h>

using namespace std;

int main(){
	int a,b,c; cin>>a>>b>>c;
	cout<<a*b*c;
}

L1-3

这题考阅读理解,对于固体流体分类讨论,比较两个数的大小判断即可

点击查看代码
#include <bits/stdc++.h>

using namespace std;

int main(){
	double a,c; int b;
	cin>>a>>b>>c;
	if(b == 1){
		double x = a*1.26;
		cout<<fixed<<setprecision(2)<<x<<" ";
		if(x<=c) cout<<"^_^"<<endl;
		else cout<<"T_T"<<endl;
	} else {
		double x = a*2.455;
		cout<<fixed<<setprecision(2)<<x<<" ";
		if(x<=c) cout<<"^_^"<<endl;
		else cout<<"T_T"<<endl;
	}
}

L1-4

签到题,倒数求和再倒数

点击查看代码
#include <bits/stdc++.h>

using namespace std;

int main(){
	int n; cin>>n;
	vector<double> a(n + 1);
	double sum = 0;
	for(int i = 1;i<=n;i++) cin>>a[i],sum += 1.0/a[i];
	cout<<fixed<<setprecision(2)<<1.0/(sum/n);
}

L1-5

稍微复杂一点的模拟题,我们需要先求胎压的最大值,统计是否误差超过阈值的个数,分类即可,只有一个就输出那个位置,大于一个就需要检查全部的轮胎

点击查看代码
#include <bits/stdc++.h>

using namespace std;

int main(){
	int a[4],b,c;
	int ma = 0;
	for(int i = 0;i<4;i++) cin>>a[i],ma = max(ma,a[i]); cin>>b>>c;
	bool flag = true;
	int cnt = 0;
	int pos = 0;
	for(int i = 0;i<4;i++){
		if(!(abs(a[i] - ma) <= c && a[i] >= b)) pos=i,flag = false,cnt++;
	}
	if(flag){
		cout<<"Normal"<<endl;
		return 0;	
	}
	if(cnt>1){
		cout<<"Warning: please check all the tires!"<<endl;
		return 0;
	}
	cout<<"Warning: please check #"<<pos+1<<"!"<<endl;
}

L1-6

求字符串是否包含 chi1 huo3 guo1,对于含有空格的字符串我们使用getline进行输入,当某一行只有 . 的时候退出循环,我们使用string的STL中的substr求子串,判断是否出现并统计个数和第一个出现的位置即可

点击查看代码
#include <bits/stdc++.h>

using namespace std;

int main(){
	string s;
	int cnt = 0;
	vector<int> ans;
	while(1){
		getline(cin,s);
		if(s == ".") break;
		cnt++;
		for(int i = 0;i+13<s.size();i++){
			if(s.substr(i,14) == "chi1 huo3 guo1"){
				ans.emplace_back(cnt);
				break;
			}
		}
	}
	cout<<cnt<<endl;
	if(ans.size() == 0){
		cout<<"-_-#"<<endl;
		return 0;
	}
	cout<<ans[0]<<" "<<ans.size()<<endl;
}

L1-7

考察二叉树的表示方法,左子树 \(\times 2\),右子树 \(\times 2 + 1\),我们直接求叶子结点的编号即可,最后需要减掉非叶子结点的编号即可

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
	int n,m; cin>>n>>m;
	while(m--){
		int ans = 1;
		string s; cin>>s;
		for(int i = 0;i<n;i++){
			if(s[i] == 'y') ans*=2;
			else if(s[i] == 'n') ans = ans*2 + 1;
		}
		cout<<(int)(ans-pow(2ll,n)+1)<<endl;
	}
}

L1-8

有点恶心的模拟题,我们提前把数字对应的金币存到数组里,已知八个数,先把刮掉的那个数找出来,按照题目三行三竖两斜统计数字和,输出对应金币即可,难在分类讨论和代码实现

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
	int n = 3;
	vector<vector<int>> a(n + 1,vector<int>(n + 1));
	vector<vector<bool>> vis(n + 1,vector<bool>(n + 1));
	vector<bool> v(30);
	vector<int> ans(30);
	ans[6] = 10000; ans[7] = 36; ans[8] = 720; ans[9] = 360; ans[10] = 80;
	ans[11] = 252; ans[12] = 108; ans[13] = 72; ans[14] = 54; ans[15] = 180;
	ans[16] = 72; ans[17] = 180; ans[18] = 119; ans[19] = 36; ans[20] = 306;
	ans[21] = 1080; ans[22] = 144; ans[23] = 1800; ans[24] = 3600;
	for(int i = 1;i<=n;i++){
		for(int j = 1;j<=n;j++){
			cin>>a[i][j]; 
			v[a[i][j]] = 1;
			if(a[i][j] == 0) vis[i][j] = 1;
		}
	}
	int d;
	for(int i = 1;i<=9;i++) if(!v[i]) d = i;
	for(int i = 1;i<=n;i++){
		for(int j = 1;j<=n;j++){
			if(a[i][j] == 0) a[i][j] = d;
		}
	}
	for(int i = 1;i<=n;i++){
		int x,y; cin>>x>>y;
		cout<<a[x][y]<<endl;
		vis[x][y] = 1;
	}
	int opt; cin>>opt;
	int now = 0;
	if(opt >= 1 && opt <= 3){
		for(int i = 1;i<=3;i++) now += a[opt][i];
	} else if(opt >= 4 && opt <= 6){
		for(int i = 1;i<=3;i++) now += a[i][opt-3];
	} else if(opt == 7){
		for(int i = 1;i<=3;i++) now += a[i][i];
	} else if(opt == 8){
		for(int i = 1;i<=3;i++)  now += a[i][n-i+1];
	}
	cout<<ans[now]<<endl;
}

L2-1

白送的后缀表达式,我们开两个栈,一个栈存符号,一个栈存数字,每次从数字栈中取出两个,符号栈取一个,运算完再塞回数字的栈(注意一下除法除数为零特判),一直循环到数字栈内只剩下一个就直接输出即可。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
	stack<int> a; stack<char> b;
	int n; cin>>n;
	for(int i = 1;i<=n;i++){
		int x; cin>>x;
		a.push(x);
	}
	for(int i = 1;i<n;i++){
		string s; cin>>s;
		b.push(s[0]);
	}
	while(a.size() >= 2){
		int y = a.top(); a.pop();
		int x = a.top(); a.pop();
//		cout<<x<<" "<<y<<endl;
		char s = b.top(); b.pop();
		if(s == '+'){
			a.push(x+y);
		} else if(s == '-'){
			a.push(x-y);
		} else if(s == '*'){
			a.push(x*y);
		} else if(s == '/'){
			if(y == 0){
				cout<<"ERROR: "<<x<<"/0"<<endl;
				return 0;
			}
			a.push(x/y);
		}
	}
	cout<<a.top()<<endl;
}

L2-2

超级无敌巨恶心的大模拟题,我们首先开一个结构体记录人的基本信息,首先判断身份证号是否合法,再将输入的时间处理一下,转换成分钟*60+秒钟,之后排序优先按照时间其次是顺序进行排序,再需要记录一下某一个人上一次拿到口罩的天数,判断是否能不能再拿,最后统计身份证号合法且健康情况异常的人(注意一下重复的问题,这里另开一个数组表示是否已经记录过),难点在代码实现和调试上

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;

int d,p;

map<string,int> last;

struct node{
	int no;
	int pos;
	string name,sfz;
	int zk;
	int t;
};

vector<node> gg;
map<string,bool> in;

bool cmp(node x,node y){
	if(x.t == y.t) return x.pos < y.pos;
	else return x.t < y.t;
}

signed main(){
	cin>>d>>p;
	for(int day = 1;day<=d;day++){
		int t,s; cin>>t>>s;
		vector<node> a(t + 1);
		for(int i = 1;i<=t;i++){
			a[i].no = 0;
			a[i].pos = i;
			cin>>a[i].name>>a[i].sfz>>a[i].zk;
			if(a[i].sfz.size() != 18) a[i].no = 1;
			for(int j = 0;j<a[i].sfz.size();j++) if(!(a[i].sfz[j] >= '0' && a[i].sfz[j] <= '9')) a[i].no = 1;
			if(!last[a[i].sfz])last[a[i].sfz] = -100;
			string tmp; cin>>tmp;
			int h,m; sscanf(tmp.c_str(),"%lld:%lld",&h,&m);
			a[i].t = h*60+m;
			if((!a[i].no) && a[i].zk == 1 && !in[a[i].sfz]) gg.emplace_back(a[i]),in[a[i].sfz]=1;
		}
		sort(a.begin() + 1,a.begin() + 1 + t,cmp);
		int cnt = 0;
		for(int i = 1;i<=t;i++){
			if(cnt==s) break;
			if(a[i].no) continue;
			if(day - last[a[i].sfz] < p+1) continue;
			last[a[i].sfz] = day;
			cout<<a[i].name<<" "<<a[i].sfz<<endl;
			cnt++;
		}
	}
	for(int i = 0;i<gg.size();i++){
		cout<<gg[i].name<<" "<<gg[i].sfz<<endl;
	}
}

L2-3

后序遍历转正常的存树方法,后序遍历按照左右根的顺序,递归下去还原树的结构,之后层序遍历使用 BFS 一层层输出即可,这题23队长还有一个做法就是后序遍历翻转变成根右左的方式,还原二叉树,直接按照顺序输出下去就是层序遍历了

点击查看代码
#include <bits/stdc++.h>

using namespace std;

const int N = 40;

int n,lim;
int diff;
int a[N];
int t[N*2];
int tot;

void dfs(int x,int dep){
	if(x>=pow(2,lim)-diff) return;
	if(dep == lim){
		t[x] = a[++tot];
		return;
	}
	if(dep < lim) dfs(x*2,dep + 1);
	if(dep < lim) dfs(x*2 + 1,dep + 1);
	t[x] = a[++tot];
}

int main(){
	cin>>n;
	for(int i = 1;i<=n;i++) cin>>a[i];
	for(int i = 0;i<=30;i++){
		if(pow(2,i) > n){
			lim = i;
			break;
		}
	}
	diff = (pow(2,lim) - 1) - n;
//	cout<<diff<<endl;
//	cout<<lim<<endl;
	dfs(1,1);
	queue<int> q;
	q.push(1);
	vector<int> ans;
	while(q.size()){
		int x = q.front(); q.pop();
		ans.emplace_back(t[x]);
		if(t[x*2]) q.push(x*2);
		if(t[x*2+1]) q.push(x*2+1);
	}
	for(int i = 0;i<ans.size();i++){
		if(i == ans.size() - 1) cout<<ans[i];
		else cout<<ans[i]<<" ";
	}
	return 0;
}
posted @ 2025-03-13 21:43  MNNUACM_2024ZY  阅读(96)  评论(0)    收藏  举报