2022 华东师范大学 数据学院复试机考(C++个人笔记)

2022 华东师范大学 数据学院复试机考

本文章参考
xwyzsn作者的《2022 华东师范大学 数据学院复试机考》

2022 华东师范大学 数据学院复试机考_华东师范大学上机考试-CSDN博客

感谢!算法会有不足之处,欢迎大家给予指导,感激不尽!

A.池化

实现一个最大池化操作

image-20220406215310037

一个filter (题目保证)filter为一个正方形且小于等于 矩阵的边长。即kx==ky<=dx,dy

输入:第一行kx,ky,dx,dy表示filter的长宽,矩阵边长

输出:经过池化操作的矩阵

样例输入

2 2 3 3

0 1 2

3 4 5

6 7 8

样例输出

4 5
7 8

#include<cstdio>
int main()
{
	int at[10][10], kx, ky, dx, dy,max;
	scanf("%d%d%d%d", &kx, &ky, &dx, &dy);
	for (int i = 0; i < dx; i++)
	{
		for (int a = 0; a < dy; a++)
		{
			scanf("%d", &at[i][a]);
		}
	}
	for (int i = 0; i <=dx - kx; i++)//列
	{
		for (int a = 0; a <= dx - kx; a++)//两层for循环实现小矩阵移动
		{
			max = 0;
			for (int x = i; x <kx+i; x++)
			{
				for (int y = a; y<ky+a; y++) {//两层for循环实现矩阵内部大小比较
					if (at[x][y] > max)
						max = at[x][y];
				}
			}
			printf("%d ", max);
		}
		printf("\n");
	}
	return 0;
}

B. 去商场


这是一道图的遍历的题目,大致意思为:若其中的坐标为为.则可以随便走,若坐标位置为#有障碍物,不能走。请问小明能不能从家走到商城,若能返回最小的步数。

输入:,m*n 地图(地图中包含 ‘#’,‘.’,‘S’,‘E’)S为起点,E为终点,#表示障碍物,.表示随意同行

输出:到达商城的最小步数,若不能返回-1

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Node {
	int length,i,j;
	char a;
	bool visited=false;
}p;
int main() {
	int m, n;
	cin >> m >> n;
	int sx, sy;
	queue<Node> q;
	string a;
	vector<vector<Node> >map(m,vector<Node>(n));//构建二维变长数组
	
	for (int i = 0; i < m; i++)
	{
		cin >> a;
		string::iterator it = a.begin();
		for (int j = 0; j < n; j++)//输入地图
		{
			map[i][j].a = *it;
			map[i][j].i = i;
			map[i][j].j = j;
			if (*it == 'S')
			{

				map[i][j].length = 0;
				q.push(map[i][j]);
				map[i][j].visited = true;
				continue;
			}
			it++;

		}
	}
	while (!q.empty())//BFS搜索最短路径
	{
		p = q.front();
		
		if(p.i!=m-1&&map[p.i+1][p.j].a!='#'&&!map[p.i + 1][p.j].visited)
		{
			map[p.i + 1][p.j].length = p.length + 1;
			if(map[p.i + 1][p.j].a=='E')
			{
				cout << map[p.i + 1][p.j].length;
				return 0;
			}
			q.push(map[p.i + 1][p.j]);
			map[p.i + 1][p.j].visited = true;
		}
		if (p.i != 0 && map[p.i - 1][p.j].a != '#' && !map[p.i -1][p.j].visited)
		{
			map[p.i - 1][p.j].length = p.length + 1;
			if (map[p.i - 1][p.j].a == 'E')
			{
				cout << map[p.i - 1][p.j].length;
				return 0;
			}
			q.push(map[p.i - 1][p.j]);
			map[p.i - 1][p.j].visited = true;
		}
		if (p.j != 0 && map[p.i ][p.j-1].a != '#' && !map[p.i][p.j-1].visited)
		{
			map[p.i ][p.j-1].length = p.length + 1;
			if (map[p.i][p.j-1].a == 'E')
			{
				cout << map[p.i ][p.j-1].length;
				return 0;
			}
			q.push(map[p.i ][p.j-1]);
			map[p.i][p.j-1].visited = true;
		}
		if (p.j != n-1 && map[p.i][p.j + 1].a != '#' && !map[p.i][p.j+1].visited)
		{
			map[p.i][p.j + 1].length = p.length + 1;
			if (map[p.i][p.j + 1].a == 'E')
			{
				cout << map[p.i][p.j + 1].length;
				return 0;
			}
			q.push(map[p.i][p.j + 1]);
			map[p.i ][p.j+1].visited = true;
		}
		q.pop();
	}
	cout << -1;
	return 0;
}

C. 数组变换


题目描述:给定一个数组序列,输出,能不能通过交换 两个相邻数(必须一奇,一偶)而构造出一个会严格递增的序列。

举例:比如[2,1,3]可以交换(1,2)->(1,2,3)可以输出YES,不可以输出NO,如[3,1,2]就没法交换得到,因为必须一奇一偶。

思路:思路大致是,判断奇数序列,和偶数序列,是否递增就可以,因为我们只能交换奇偶,如果因为奇偶我们总能通过交换让她有序。

#include <iostream>
#include<algorithm>
#include <vector>
using namespace std;
int main()
{
	vector<int> a;
	int n,x;
	cin >> n;
	bool flag = true;
	for (int i = 0; i < n; i++)
	{
		cin >> x;
		a.push_back(x);
	}
	for (int i = 1; i < n; i++)
	{
		if (a[i] < a[i - 1] && (a[i] + a[i - 1]) % 2 == 0)
		{
			cout << "NO";
			return 0;
		}
		if (a[i] < a[i - 1] && (a[i] + a[i - 1]) % 2 != 0 && flag)
		{
			flag = false;
			swap(a[i], a[i - 1]);
		}
		if(a[i]<a[i-1]&&!flag)
		{
			cout << "NO";
			return 0;
		}
	}
	cout << "YES";
	return 0;
}

D. 表情拦截


题目描述:大致为,给定这样一个序列 1,2,3,4,...k,k-1,k-2....1然后给出一个x,若序列的和超过x,后面就会被忽略,输出被截断的位置的行数。

举例:k=3,x=4,[1,2,3,2,1],x=4 那么在第三行就会被截断。

#include <iostream>
#include <cmath>
using namespace std;
int cal(int a) {
	return (a*(1+a)) / 2;
}
using namespace std;
int main()
{
	int a, k;
	cin >> a >> k;
	if (a <= cal(k))
	{
		cout << 1 + (int)(sqrt(1 + 8 * a) - 1) / 2; return 0;
	}
	else if (a > cal(k) && a < cal(k) + cal(k - 1))
	{
		int x = cal(k) + cal(k - 1);
		int y = 1 + 8 * x - 8 * a;
		float t =(- 1 + sqrt(y * 1.0) ) / 2;
		if (x == a + cal((int)(-1 + sqrt(y * 1.0)) / 2))
			cout << 2*k-(int)t ;
		else cout << 2 * k - 1 - (int)t;
	}

	

	else cout << "no";
			
	return 0;
}

E .拍照队列


描述:给定一个序列010101其中0表示男生,1表示女生。现在要求任意截取一个子串(length>1)都要满足男生数量不大于女生数量。即010这是合法的0101这是不合法的因为存在010这一个字串不满足。请返回至少要添加几个1满足合法序列。

举例:000->0110110 需要添加四个1

输入:n表示有几个人,s表示一个01的串。输出:最少要添加几个女生

思路:应该要确保两个0之间要有两个1

#include <iostream>
#include <vector>
using namespace std;
int main()
{
	vector<char> str;
	string a;
	int count = 0,sum=0,j;
	cin >> a;
	string::iterator it = a.begin();
	for (it; it != a.end(); it++)
		str.push_back(*it);
	for(int i=0;i<str.size()-1;i++)
		if (str[i] == '0')
		{
			count = 0;
			j = i + 1;
			while (j < str.size()&&str[j] != '0')
			{
				j++; count++;
				if (count == 2)
					break;

			}
			if(count<2)
				sum += (2 - count); 
		}
	cout << sum;
	return 0;
}

F. 树上的异或和


描述:给定一个树的前序,中序序列,要求你算出根节点的“值”。值的定义如下

叶子节点:值为从根节点到叶子节点的最短路径长度,即边长

非叶子节点

左右孩子都有的:值定义为左右孩子的 异或
只有左孩子的:值定义为左孩子的两倍(做到后面才发现题目没有说他一定是一个满二叉树,所以代码写的都不太对。)
请你返回根节点的“值”

举例:

输入

7(有几个节点)

1 2 4 5 3 6 7(前序),这里的数字只代表这个节点不代表值

4 2 5 1 6 3 7 (中序)

输出:

0

#include <iostream>
using namespace std;
struct Node {
	int data,layer=0;
	Node* lchild;
	Node* rchild;

};
const int maxn = 50;
int pre[maxn], in[maxn];
Node* Btree(int preL,int preR,int inL,int inR,int l) {
	if (preL > preR)
		return NULL;
	Node* p = new Node;
	p->data = pre[preL];
	p->layer = l;
	int k;
	for (k = inL; k < inR; k++)
	{
		if (in[k] == pre[preL])
			break;
	}
	int Lnum = k - inL;
	p->lchild = Btree(preL + 1, preL+Lnum, inL, k - 1,l+1);
	p->rchild = Btree(preL + Lnum + 1, preR, k + 1, inR,l+1);
	return p;
}
int cal(Node* root) {
	if (root->lchild == NULL && root->rchild == NULL)
		return root->layer;
	else if (root->rchild == NULL)
		return 2 * cal(root->lchild);
	else
		return cal(root->lchild) ^ cal(root->rchild);
}
int main()
{
	for (int i = 0; i < 7; i++)
		cin >> pre[i];
	for (int i = 0; i < 7; i++)
		cin >> in[i];
	Node* root=Btree(0, 6, 0, 6, 0);
	int x = cal(root);
	cout << x;
	return 0;
}

  • 40
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值