天梯赛题目1

L1-019 谁先倒

链接
甲、乙两人的酒量(最多能喝多少杯不倒),没注意到是喝多少杯不倒。。。
a、b来表示甲乙,1、2来来表述属性,以免混乱。

#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    int maxa, maxb;
    int n;
    scanf("%d%d%d", &maxa, &maxb, &n);
    int nowa = 0, nowb = 0;
    for(int i = 1; i <= n; i++) {
    	int a1, a2, b1, b2;
    	scanf("%d%d%d%d", &a1, &a2, &b1, &b2);
    	int ans = a1 + b1;
    	if(a2 == ans && b2 != ans) {
    		nowa++;
		}
		else if(b2 == ans && a2 != ans) {
			nowb++;
		}
		if(nowa > maxa) {
			printf("A\n");
			printf("%d", nowb);
			break;
		}
		else if(nowb > maxb) {
			printf("B\n");
			printf("%d", nowa);
			break;
		}
	}
}

L2-006 树的遍历

链接
后序数组中最后一个元素即为根,找到对应中序数组中的位置,确定左右子树节点个数,递归即可。在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int b[35];
int c[35];
int tLeft[35];
int tRight[35];
int n;
int build(int lb, int rb, int lc, int rc) {
	if(lb > rb) return 0;
	int root = c[rc];
	int index = 0;
	//找到根节点在中序数组中的位置 
	while(b[index] != root) index++;
	int count = index - lb;
	tLeft[root] = build(lb, index-1, lc, lc+count-1);
	tRight[root] = build(index+1, rb, lc+count, rc-1);
	return root;
}
void print(int root) {
	queue<int> q;
	q.push(root);
	int count = 1;
	while(!q.empty()) {
		int now = q.front();
		printf("%d", now);
		if(count != n) printf(" ");
		count++;
		q.pop();
		if(tLeft[now] != 0) q.push(tLeft[now]);
		if(tRight[now] != 0) q.push(tRight[now]);
	}
}
int main() {
	scanf("%d", &n);
	for(int i = 0; i < n; i++) scanf("%d", &c[i]);
	for(int i = 0; i < n; i++) scanf("%d", &b[i]);
	int root = build(0, n-1, 0, n-1);
	print(root);
}

L2-004 这是二叉搜索树吗?

链接
数组存储前序遍历序列,第一个元素为根。sl从左往右扫描,看是否都小于根,sr从右往左扫描,看是否都大于根。递归左右子树,最后将根添加到ans中,ans保存的即为后序序列。
注意:其右子树中所有结点的键值大于等于该结点的键值。

#include <iostream>
#include <cstdio>
#include <vector> 
using namespace std;
int a[1005];
int flag;
vector<int> ans;
void judge(int l, int r) {
	if(l > r) return;
	int sl = l + 1;
	int sr = r;
	//非镜像 
	if(flag == 0) {
		while(sl <= r && a[sl] < a[l]) sl++;
		//a[l]为根 
		while(sr > l && a[sr] >= a[l]) sr--;
	}
	//镜像 
	else {
		while(sl <= r && a[sl] >= a[l]) sl++;
		while(sr > l && a[sr] < a[l]) sr--;
	}
	if(sl - sr != 1) return;
	judge(l+1, sr);
	judge(sl, r);
	ans.push_back(a[l]);
}
int main() {
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	judge(0, n-1);
	if(ans.size() != n) {
		flag = 1;
		ans.clear();
		judge(0, n-1);
	}
	if(ans.size() != n) printf("NO\n");
	else {
		printf("YES\n");
		for(int i = 0; i < n; i++) {
			printf("%d", ans[i]);
			if(i != n-1) printf(" ");
		}
	}
}

L2-019 悄悄关注

链接
使用map,输入被其关注的用户的ID时,映射value为1。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring> 
#include <map>
using namespace std;
map<string, int> mp;
struct node {
	char id[5];
	int num;
} b[10005];
int flag[10005];
bool cmp(node a, node b) {
	return strcmp(a.id, b.id) < 0;
}
int main() {
	int n, m, sum = 0;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		char s[10];
		scanf("%s", s);
		mp[s] = 1;
	}
	scanf("%d", &m);
	for(int i = 0; i < m; i++) {
		scanf("%s%d", b[i].id, &b[i].num);
		sum += b[i].num;
	}
	sort(b, b+m, cmp);
	float avg = 1.0 * sum / m;	
	for(int i = 0; i < m; i++) {
		if(mp[b[i].id] == 0) flag[i] = 1; 
	}
	int mark = 0;
	for(int i = 0; i < m; i++) {
		if(flag[i] == 1 && b[i].num > avg) {
			printf("%s\n", b[i].id);
			mark = 1;
		}
	}
	if(mark == 0) printf("Bing Mei You");
}

L2-032 彩虹瓶

链接
简单堆栈模拟

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
stack<int> s;
int main() {
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= k; i++) {
		int now = 1;
		int flag = 0;
		while(!s.empty()) s.pop();
		for(int j = 1; j <= n; j++) {
			int next;
			scanf("%d", &next);
			if(next == now) {
				now++;
				while(!s.empty()) {
					if(s.top() == now) {
						s.pop();
						now++;
					}
					else break;
				}
			}
			else {
				s.push(next);
				if(s.size() > m) {
					flag = 1;
					//break;
				}
			}
		}
		if(s.size() == 0 && flag == 0) printf("YES\n");
		else printf("NO\n");
	}
}

L2-024 部落

链接
使用set容器统计社区的总人数。因为所有人的编号从1开始连续编号,所以扫描set集合时,下标i即对应每个人的编号。也可以用迭代器。

//直接扫描
for(int i = 1; i <= s.size(); i++) {
	if(fa[i] == i) {
		ans++;
	}
}
//迭代器
for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
	if(fa[*it] == *it) {
		ans++;
	}
}
#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
int fa[10005];
set<int> s;
void init() {
	for(int i = 1; i <= 10000; i++) {
		fa[i] = i;
	}
}
int get(int x) {
	if(x == fa[x]) return x;
	return fa[x] = get(fa[x]);
}
void merge(int x, int y) {
	x = get(x);
	y = get(y);
	if(x != y) {
		fa[x] = y;
	}
}
bool judge(int x, int y) {
	if(get(x) == get(y)) return true;
	return false;
}
int main() {
	int n;
	scanf("%d", &n);
	init();
	for(int i = 1; i <= n; i++) {
		int k, a, last;
		scanf("%d", &k);
		for(int j = 1; j <= k; j++) {
			scanf("%d", &a);
			if(j != 1) {
				merge(last, a);				
			}
			last = a;
			s.insert(a);
		}
	}
	int ans = 0;
//	for(int i = 1; i <= s.size(); i++) {
//		if(fa[i] == i) {
//			ans++;
//		}
//	}
	for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
		if(fa[*it] == *it) {
			ans++;
		}
	} 
	printf("%d %d\n", s.size(), ans);
	int q;
	scanf("%d", &q);
	for(int i = 1; i <= q; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		if(judge(x, y)) printf("Y\n");
		else printf("N\n");
	}
}

L3-003 社交集群

链接
创建一个habit数组,存储每个爱好的祖先。当输入某个人的这个爱好时,就与这个爱好的祖先合并。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int fa[1005];
int habit[1005];
int isRoot[1005];
int n;
int cmp(int a, int b) {
	return a > b;
}
void init() {
	for(int i = 1; i <= n; i++) {
		fa[i] = i;
	}
}
int get(int x) {
	if(x == fa[x]) return x;
	return fa[x] = get(fa[x]);
}
void merge(int x, int y) {
	x = get(x);
	y = get(y);
	if(x != y) {
		fa[x] = y;
	}
}
int main() {
	scanf("%d", &n);
	//每个人有k个爱好,每个爱好为h
	int k, h; 
	init(); 
	for(int i = 1; i <= n; i++) {
		scanf("%d:", &k);
		for(int j = 1; j <= k; j++) {
			scanf("%d", &h);
			if(habit[h] == 0) {
				//这个爱好的根节点为第i人 
				habit[h] = i;
			}
			//将i与有相同爱好的人合并
			merge(i, habit[h]);
		}
	}
	int ans = 0; 
	for(int i = 1; i <= n; i++) {
		isRoot[get(i)]++ ; 
	}
	for(int i = 1; i <= n; i++) {
		if(isRoot[i] != 0) {
			ans++;
		}
	}
	printf("%d\n", ans);
	sort(isRoot+1, isRoot+1+n, cmp);
	for(int i = 1; i <= ans; i++) {
		printf("%d", isRoot[i]);
		if(i != ans) printf(" ");
	}
	printf("\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值