PAT甲级_2022秋

本文介绍了四道编程考试题目,涉及滑动窗口算法、动态规划解决最大子序列问题、图论中的意见领袖识别以及二叉树类型的判断和后序遍历。文章提供了解题思路,包括利用邻接表处理图、构建和分析二叉树结构等,并对快速排序的特性进行了讨论。
摘要由CSDN通过智能技术生成

总结

第三次模考,88分。
20 17 25 26
挺糟糕的一次体验,提交了后需要等30min才能等到结果,考试得避开晚上9:00 - 12:00。
请添加图片描述

第一题

思路

滑动窗口,顺序扫描即可。

第二题

思路(代码待测试)

DP,分别从前往后、从后往前扫描,用两个数组分别记录下标i(含i)之前最大值、之后最小值。
然后扫描两个数组相同下标的数值是否相同,记录相同数量。
cnt == 3 或(cnt == 2 && (数组起始元素相同 || 末尾元素相同))输出Yes,否则输出No。

小结

  1. 注意快排特性,枢轴左侧所有元素小于枢轴,枢轴右侧元素大于枢轴。
  2. 做题时初始思路是给数组排序,遍历到初始位置和最终位置相同的元素时cnt++,这是不充分的条件。

第三题

题意

给一个有向图,和一个阈值T,入度in和出度out的比例大于等于T的被称为意见领袖。被最多意见领袖关注的意见领袖被称为意见领袖的意见领袖。升序输出其序号。

思路

  • N小于1E4,邻接矩阵、邻接表都行,这里用邻接表存图。
  • 构图同时更新每个结点的出度和入度。
  • 遍历所有节点得到意见领袖存到数组rec,并用数组st作为哈希表记录该节点为意见领袖。
  • 遍历所有意见领袖的结点和与之相连的边,看是否有关注其他意见领袖,更新数组cnt记录被其他领袖关注的次数。
  • 遍历cnt数组得到意见领袖的意见领袖。

第四题

题意

给出结点数n,给出树的中序和先序序列。判断这棵树是满二叉树?完全二叉树?或pseudo-completeness二叉树?或什么也不是。然后输出后序遍历序列。

思路(代码待测试)

  • 常规造树。
  • 造树同时获得后序遍历序列post,同时记录每层结点个数,更新最大深度max_h,同时将遍历到的叶子结点的深度入数组。
  • 判断是什么树:
    • 如果最大深度对应结点个数是pow(2, max_h)则是满二叉树
    • 如果倒数第二层没满cnt[max_h - 1] != pow(2, max_h - 1)则什么树都不是。
    • 然后看叶子深度的序列是否单调递减,是则是完全二叉树,否则是p树。

小结

  • 找规律后可以避免麻烦的板子,比如这题不需要单独一次后续遍历、不需要层序遍历。
  • 考试的时候用的层序判断,应该是有细节没注意,导致没AC,ps以下代码未测试。

7-1 Balloon Popping

Balloon popping is a fun game for kids. Now n balloons are positioned in a line. The goal of the game is very simple: to pop as many balloons as possible. Here we add a special rule to this game – that is, you can only make ONE jump. Assume that a smart baby covers his/her body by thorns(刺), jumps to some position and lies down (as shown by the figures below), so that the balloons will be popped as soon as they are touched by any part of the baby’s body. Now it is your job to tell the baby at which position he/she must jump to pop the most number of balloons.

Input Specification:

Each input file contains one test case. For each case, two positive integers are given in the first line: n (≤105), the number of balloons in a line, and h (≤103), the height of the baby with his/her arms stretched up. Then n integers are given in the next line, each corresponds to the coordinate of a balloon on the axis of the line. It is guaranteed that the coordinates are given in ascending order, and are all in the range [−106,106].

Output Specification:

Output in a line the coordinate at which the baby shall jump, so that if the baby jumps at this position and then lie down, the maximum number of the balloons can be popped beneath his/her body. Then also print the maximum number of balloons that can be popped. If the coordinate is not unique, output the smallest one.

The numbers must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

11 120
-120 -40 0 80 122 140 160 220 240 260 300

Sample Output:

120 5
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int rec[N], n, h, num, ans, tmp;
queue<int> cnt;
int main(){
	cin>>n>>h;
	for(int i = 0; i < n; i++){
		cin>>tmp;
		while(cnt.size() && tmp - cnt.front() > h) cnt.pop();
		cnt.push(tmp);
		if(num < cnt.size()){
			num = cnt.size();
			ans = tmp - h;
		}
	}
	cout<<ans<<' '<<num;
	return 0; 
}

7-2 The Second Run of Quicksort

“During the sorting, processing every element which is not yet at its final position is called a run. Which of the following cannot be the result after the second run of quicksort?” – This is a question in the Graduate Entrance Exam set. Now you are supposed to write a program to check the answers automatically.

Input Specification:

Each input file contains several test cases. The first line gives a positive integer K (≤10), which is the total number of cases. Then K cases are given in the fomat

N
a[0] a[1] ... a[N-1]

where N (3≤N≤105) is the number of elements, and a[i]'s (≤109) are distinct elements to be checked. All the numbers in a line are positive integers that are separated by spaces.

Output Specification:

For each test case, output in a line Yes if it is possible to be the second run of quicksort, or No if not.

Sample Input:

4
8
5 2 16 12 28 60 32 72
8
2 16 5 28 12 60 32 72
8
2 12 16 5 28 32 72 60
8
5 2 12 28 16 32 72 60

Sample Output:

Yes
Yes
Yes
No
#include<bits/stdc++.h>
using namespace std;
int n, k, a[100010], b[100010], c[100010];
bool test(){
	b[0] = a[0], c[k - 1] = a[k - 1];
	for(int i = 1; i < k; i ++) b[i] = max(b[i - 1], a[i]);
	for(int i = k - 2; i >= 0; i --) c[i] = min(c[i + 1], a[i]);
	int cnt = 0;
	for(int i = 0; i < k; i ++) if(b[i] == c[i]) cnt++;
	return (cnt == 3 ||(cnt == 2 && (b[0] == c[0] || b[k - 1] == c[k - 1]))) ? true : false;
} 
int main(){
	cin>>n;
	while(n--){
		scanf("%d", &k);
		for(int i = 0; i < k; i ++) scanf("%d", &a[i]);
		puts(test() ? "Yes" : "No");
	}
	return 0;
} 

7-3 Leader of the Opinion Leaders

Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may follow many other users as well.

According to Wikipedia, opinion leadership is leadership by an active media user who interprets the meaning of media messages or content for lower-end media users. Typically opinion leaders are held in high esteem by those who accept their opinions.

To be more specific, let’s define an opinion leader index OLI to be Nin​/Nout​, where Nin​ is the number of one’s followers and Nout​ is the number of users that one follows on Weibo. Then for any given threshold T, we call those users whose OLI is at least T the opinion leaders.

Some of the opinion leaders may follow each other. An opinion leader who has the most number of other opinion leaders following him/her is defined to be the leader of the opinion leaders. Your job is to find those leaders of the opinion leaders.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤104), the number of users; and T (≤100), the threshold for OLI. Hence it is assumed that all the users are numbered from 1 to N, and those users whose OLI is at least T is the opinion leaders.

Then N lines follow, each in the format:

M[i] user_list[i]

where M[i] (≤100) is the total number of people that user[i] follows and is always positive; and user_list[i] is a list of the indices of the M[i] users that are followed by user[i]. It is guaranteed that no one can follow oneself, and all the indices in a user_list[i] are distinct. All the numbers are separated by a space.

Output Specification:

Print in one line all the leaders of the opinion leaders, in ascending order of their indices.

It is guranteed that there is at least one ouput. All the numbers must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

10 3
3 9 3 8
2 1 3
2 9 7
3 2 7 5
3 6 3 7
2 7 3
1 2
2 3 9
1 10
1 3

Sample Output:

7 9
#include<bits/stdc++.h>
using namespace std;
const int N = 30001, M = 2e8+2;
int in[N], out[N];
int e[M], h[N], ne[M], idx, cnt[N];
bool st[N]; 
void add(int a, int b){
	e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
}
int main(){
	int n, t, m, f; cin>>n>>t;
	memset(h, -1, sizeof h);
	for(int i = 1; i <= n; i++){
		scanf("%d", &m);
		out[i] += m;
		for(int j = 1; j <= m; j++){
			scanf("%d", &f);
			add(i, f);//i关注了f 
			in[f] ++;
		}
	}
	vector<int> rec;
	for(int i = 1; i <= n; i++)
		if(in[i] / out[i] >= t) {
			st[i] = 1, rec.push_back(i);
		}
	for(auto i : rec){
		for(int j = h[i]; j != -1; j = ne[j]){
			int v2 = e[j];
			if(st[v2])cnt[v2]++;
		} 
	}
	vector<int> ans;
	int max_cnt = -1;
	for(int i = 1; i <= n; i++){
		if(max_cnt > cnt[i] || !st[i]) continue;
		else if(max_cnt < cnt[i]){
			ans.clear();
			ans.push_back(i);
			max_cnt = cnt[i];
		}else if(max_cnt == cnt[i])
			ans.push_back(i);
	}
	for(int i = 0; i < ans.size(); i ++){
		if(i != 0) cout<<' ';
		cout<<ans[i];
	}
	return 0; 
}
//8min
//2 5 12 16 28 32 60 72 

7-4 Pseudo-completeness

In computer science, a perfect binary tree is a binary tree in which all non-leaf nodes have two children and all leaves have the same depth. In a complete binary tree, every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. A pseudo-complete binary tree is a binary tree that becomes a perfect tree when the bottom level is removed.

Given the inorder and preorder traversal sequences of a binary tree, you are supposed to tell the type of this tree, and output its postorder traversal sequence.

Input Specification:

Each input file contains one test case. The first line gives a positive integer N (≤2000) which is the number of nodes in the tree. Then the following two lines contain the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that all the keys are distinct, and in the range of int. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in a line the type of the given tree: 1 for perfect binary tree, 2 for complete binary tree (but not of type 1), 3 for pseudo-complete binary tree (but not of types 1 or 2); and 0 for a binary tree of other types. Then in the second line, output the postorder traversal sequence of the tree. All the numbers in a line are separated by 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input 1:

7
4 2 5 1 6 3 7
1 2 4 5 3 6 7

Sample Output 1:

1
4 5 2 6 7 3 1

Sample Input 2:

10
8 4 9 2 10 5 1 6 3 7
1 2 4 8 9 5 10 3 6 7

Sample Output 2:

2
8 9 4 10 5 2 6 7 3 1

Sample Input 3:

10
8 4 2 5 11 1 6 3 14 7
1 2 4 8 5 11 3 6 7 14

Sample Output 3:

3
8 4 11 5 2 6 14 7 3 1

Sample Input 4:

7
4 2 10 5 1 3 7
1 2 4 5 10 3 7

Sample Output 4:

0
4 10 5 2 7 3 1
#include<bits/stdc++.h>
using namespace std;
int n, in[2001], pre[2001], cnt[2001], max_h; 
vector<int> post, rec;
struct node{
	int k;
	struct node* l,* r;
};
node* mt(int pl, int pr, int il, int ir, int h){
	if(il > ir) return NULL;
	node *t = (node*)malloc(sizeof(node));
	t->k = pre[pl];
	cnt[h]++;
	max_h = max(max_h, h);
	int i = il;
	while(in[i] != pre[pl]) i++;
	t->l = mt(pl + 1, pl + i - il, il, i - 1, h + 1);
	t->r = mt(pl + i - il + 1, pr, i + 1, ir, h + 1);
	post.push_back(t->k);
	if(!t->l && !t->r) rec.push_back(h);
	return t;
} 
int main(){
	scanf("%d", &n);
	for(int i = 0; i < n; i ++) scanf("%d", &in[i]);
	for(int i = 0; i < n; i ++) scanf("%d", &pre[i]);
	node * t = mt(0, n - 1, 0, n - 1, 0);
	if(cnt[max_h] == pow(2, max_h))puts("1");
	else if(cnt[max_h - 1] == pow(2, max_h - 1)){
		bool flag = false;
		for(int i = 1; i < rec.size(); i ++)
			if(rec[i] > rec[i - 1]) flag = true;
		puts(flag ? "3" : "2");
	}else puts("0");
	for(int i = 0; i < post.size(); i ++){
		printf("%d", post[i]);
		if(i != post.size() - 1) printf(" ");
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值