2023.3.19-团体程序设计天梯赛-练习集-1

文章提供了几个编程题目,包括使用两个栈实现简单计算器,模拟口罩发放过程,完全二叉树的层序遍历,以及涉及图论的网红点打卡攻略和分而治之策略的问题。这些题目涵盖了数据结构和算法的不同方面,如栈、图遍历和搜索策略。
摘要由CSDN通过智能技术生成

目录:

题目解析:

1、简单计算器

看题目就可以知道,这里题目要求的是用两个栈来模拟这个简单计算器,简单题目没什么好说的(

#include<bits/stdc++.h>
using namespace std;
int main() {
	int n,x1,x,y;
	char x2;
	stack<int>a;
	stack<char>b;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> x1;
		a.push(x1);
	}
	for(int i=1; i<n; i++) {
		cin >> x2;
		b.push(x2);
	}
	while(!b.empty()) {
		y=a.top();
		a.pop();
		x=a.top();
		a.pop();
		x2=b.top();
		b.pop();
		if(x2=='+') {
			x+=y;
		} else if(x2=='-') {
			x-=y;
		} else if(x2=='*') {
			x*=y;
		} else {
			if(y==0) {
				cout << "ERROR: " << x << "/0";
				return 0;
			}
			x/=y;
		}
		a.push(x);
	}
	cout << a.top();
	return 0;
}

2、口罩发放

 这道题是一道比较复杂的模拟,需要用到结构体排序,以及处理题目给定条件的判断问题,虽然复杂但是难度却不高。

#include<bits/stdc++.h>
using namespace std;
struct name {
	string name;
	string id;
	int situ;
	string time;
	int od;
} a[30010],b[30010];
bool cmp(name x,name y) {
	if(x.time!=y.time) {
		return x.time<y.time;
	} else {
		return x.od<y.od;
	}
}
bool check(string id) {
	if(id.size()!=18) {
		return false;
	}
	for(int i=0; i<18; i++) {
		if(id[i]<'0'||id[i]>'9') {
			return false;
		}
	}
	return true;
}
map<string,int>mp;
map<string,int>mp2;
int main() {
	int d,p;
	cin >> d >> p;
	int t,s;
	int sum=0;
	for(int i=1; i<=d; i++) {
		cin >> t >> s;
		for(int j=1; j<=t; j++) {
			cin >> a[j].name >> a[j].id >> a[j].situ >> a[j].time;
			a[j].od=j;
		}
		for(int j=1; j<=t; j++) {
			if(check(a[j].id)!=true) {
				continue;
			}
			if(a[j].situ==1&&mp[a[j].id]==0) {
				mp[a[j].id]=1;
				sum++;
				b[sum].name=a[j].name;
				b[sum].id=a[j].id;
			}
		}
		sort(a+1,a+1+t,cmp);
		int normal=0;
		for(int j=1; j<=t; j++) {
			if(check(a[j].id)!=true) {
				continue;
			}
			if(normal<s) {
				if(mp2[a[j].id]==0||mp2[a[j].id]+p+1<=i) {
					mp2[a[j].id]=i;
					normal++;
					cout << a[j].name << " " << a[j].id << endl;
				}
			}
		}
	}
	for(int k=1; k<=sum; k++) {
		cout << b[k].name << " " << b[k].id << endl;
	}

	return 0;
}

3、完全二叉树的层序遍历

这道题想必大家都很熟悉了,学二叉树的时候都做过 。

#include<bits/stdc++.h>
using namespace std;
int Level[50], res[50];
int n,p=0;
void postFind(int node) { 
	if (node > n) return;
	postFind(2*node);
	postFind(2*node + 1);
	res[node-1]=Level[p++];
}

int main() {
	int temp;
	cin >> n;
	for (int i=0; i<n; i++) {
		cin >> temp;
		Level[i] = temp;
	}
	postFind(1);
	cout << res[0];
	if (n > 1) {
		for (int i = 1; i < n; i++)
		{
			cout << " " << res[i];
		}
	}
	return 0;
}

4、网红点打卡攻略

这题是一道图论题,重点在于几种遍历的方案,每一种方案都要求:要遍历完所有的结点,并且每个结点只能遍历一遍,最后把遍历的这些结点的边权值加到一起,最后到回到原点,如果方案的最后一个结点和原点没有边,也是不可以的。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200 + 5;
int m,N,sx;//sx就是序号
int mincost = 1e9 + 1;
int Graph[200][200];
int vec[200];
int visit[200];
int main() {
	cin >> N >> m;
	int u,v,w;
	for(int i=0; i<m; i++) {
		cin >> u >> v >> w;
		Graph[u][v] = Graph[v][u] = w;
	}
	int num =0;
	int k,n;
	cin >> k;
	for(int j=1; j<=k; j++) {
		int sum = 0;
		cin>>n;
		memset(visit,0,sizeof(visit));
		for(int i=1; i<=n; i++) {
			cin >> vec[i];
			visit[vec[i]]++;
		}
		vec[0] = vec[n+1]=0;
		if(N != n) {
			continue;
		}

		for(int i=1; i<=N; i++) {
			if(visit[i]!=1) {
				n--;
			}
		}
		if(N!=n) {
			continue;
		}
		for(int i=0; i<=n; i++) {
			if(Graph[vec[i]][vec[i+1]]==0) {
				n--;
				break;
			}
			sum+=Graph[vec[i]][vec[i+1]];
		}
		if(N!=n) {
			continue;
		}
		num++;
		if(mincost>sum) {
			mincost=sum;
			sx=j;
		}
	}
	cout << num << endl << sx << " " << mincost;
}

5、分而治之

 这题就是用邻接表存图,aa数组表示此城有兄弟城市(即有多少城市与之连接),a组为每次攻城后的次城有多少兄弟城,aa作为原始连接情况,不变,每次用的时候,复制到a上即可。每攻下一座城,次城兄弟成变成0,其兄弟城的兄弟城减少一个。最后检查,如果所有城市的兄弟城都小于零,则输出YES,否则输出NO。

#include <bits/stdc++.h>
using namespace std;
int n,m,k,aa[10010],a[10010];
void check() {
    for(int i=1;i<=n;i++) {
        if(a[i]>0) {
            cout << "NO" << endl;
            return ;
        }
    }
    cout << "YES" << endl;
    return ;
}
int main(){
    cin >> n >> m;
    vector<vector<int>> v(n+1);
    while(m--) {
        int c1, c2;
        cin >> c1 >> c2;
        aa[c1]++;
        aa[c2]++;
        v[c1].push_back(c2);
        v[c2].push_back(c1);
    }
    cin >> k;
    while(k--) {
        int cnt, num;
        cin >> cnt;
        for(int i=1;i<=n; i++)
        {
        	a[i] = aa[i];
		}
        for(int i=0;i<cnt; i++) {
            cin >> num;
            a[num]=0;
            for(int j=0;j<v[num].size();j++)
            {
            	a[v[num][j]]--;
			}
        }
        check();
    }
    return 0;
}

 6、小字辈

这题就是存储每个节点people[]以及其孩子root。然后进行bfs计算最深的层数,然后输出最深层的所有子结点即可。 

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
vector<int> root[N];
int people[N],depth[N];
int n;
int bfs() {
	int ans=0;
	queue<int> q;
	q.push(root[0][0]);
	int t;
	while(q.size()) {
		t=q.front();
		q.pop();
		for(int j=0; j<root[t].size(); j++) {
			q.push(root[t][j]);
			depth[root[t][j]]=depth[t]+1;
		}
	}
	return depth[t];
}
int main() {
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> people[i];
		if(people[i]==-1) {
			people[i]=0;
		}
	}
	for(int i=1; i<=n; i++) {
		root[people[i]].push_back(i);
		if(people[i]==0)
			depth[i]=1;
	}
	int ger=bfs();
	cout << ger << endl;
	int f=0;
	for(int i=1; i<=n; i++) {
		if(depth[i]==ger) {
			if(f) {
				cout<<" ";
			}
			cout << i;
			f=1;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值