当前位置: 首页 > news >正文

【C++】 —— 笔试刷题day_21

一、爱丽丝的人偶

题目解析

在这里插入图片描述

现在存在n个玩偶,每个玩偶的身高是1、2、3......n

现在我们要对这些玩偶进行排序(如果x人偶,它左右两边的玩偶一个比x高、一个比x矮,那这个玩偶就会爆炸)。

我们不想要任何一个人偶爆炸,题目输入一个n,让我们返回满足条件的排列。

算法思路

这道题,可以说比较简单了,我们要让i人偶比i-1i+1位置的人偶高或者低;

我们可以这样去排列:1, n , 2 , n-1 , 3 , n-2......

这样我们可以发现,任何一个位置,它都是比左右两个人偶高或者低的;

那这道题我们就可以从1n开始放置人偶,所以只需要定义两个变量分别从1n开始向中间遍历。

**这里有一个要注意的点:**当我们放置完l人偶后,l是可能等于r

如果我们不做判断,那就可能放置两个身高一样的人偶:1 3 2 2

所以我们要进行判断,如果放置完l的人偶后,让l++,再判断l是否小于等于r:(如果l<=r就放置r,否则就不放置)。

这里我们也没有必要将数据存储起来,直接输出即可。

代码实现

#include<iostream>
using namespace std;
int main()
{int n;cin>>n;int l = 1,r = n;while(l<=r){cout<<l<<' ';l++;if(l<=r){cout<<r<<' ';r--;}}cout<<endl;return 0;
}

二、集合

题目解析

在这里插入图片描述

题目给定两个集合(数组)AB,让我们求出AB的交集(A+B);

输出时要求按照升序输出。

算法思路

对于这道题,就类似于归并排序中,合并两个数组的操作,但是这道题目求的是交集,也就是最后结果中不能存在相同的元素。

思路一:排序+合并数组

对于AB,题目并没有说这两个数组是有序的,那我们要进行和并数组操作就要先对AB进行排序;

排完序之后,我们使用lr分别遍历两个数组(注意:要求升序且不能存在重读元素

如果l位置元素等于r位置元素就先加入到结果数组中,让r++(或者l++);

如果l位置元素大于r位置元素,就将r位置元素加入到结果数组中;

如果l位置元素小于r位置元素,就将l位置元素加入到结果数组中。

最后遍历结束之后,lr可能没有遍历完,所以要将A或者B中剩余的元素加入到结果数组中。

思路二:set去重+排序

对于这种思路就有一点投机取巧了:

set中是不允许出现重复元素的,并且set底层是红黑树,是一个平衡搜索二叉树;使用迭代器遍历是有序的。
在这里插入图片描述

代码实现

#include <iostream>
#include <set>
using namespace std;int main() {int n, m;cin >> n >> m;//set去重+排序set<int> ret;int x;for (int i = 0; i < n; i++) {cin >> x;ret.insert(x);}for (int i = 0; i < m; i++) {cin >> x;ret.insert(x);}for (auto& e : ret) {cout << e << ' ';}cout << endl;
}

三、最长回文子序列

题目解析

在这里插入图片描述

题目给定一个字符串str,然后让我们在这个字符串中找到最长的回文子序列,然后输出它的长度。

算法思路

对于这道题,初看可能没什么思路

这里我们可以选取不连续的元素构成子序列,那这如何去找啊?

先说整道题用什么方法去解决:动态规划

要使用动态规划去解决这道问题,那我们就要搞清楚状态表示和状态转移方程

状态表示: dp[i][j]表示区间[i,j]内最长的回文子序列的长度

**状态转移方程:**对于状态转移方程,这里就要好好的分析一下了:

dp[i][j]表示的是区间[i,j]内最长的回文子序列的长度,但是可能i>j或者i == j或者i<j

  • i > j:这种情况肯定是不存在区间[i,j]的,那此时dp[i][j] = 0

  • i == j:这种情况,区间[i,j]只有一个元素,那此时这一个元素它可以构成一个回文子序列;所有dp[i][j] = 1

  • i < j:这种情况,区间[i,j]内是大于等于2个元素的;这时候我们就要看i位置和j位置是否相等了。

    如果str[i] == str[j],区间[i,j]中最长回文子序列的长度就等于[i+1,j-1]中最长回文子序列的长度再加上2

    如果str[i] == str[j],我们不能直接去找区间[i+1,j-1]内的最长回文子序列 ,因为i+1位置的元素和j位置的元素、i位置的元素和j-1位置的元素是可能相等的;所以我们要找的就是区间[i+1,j]和区间[i,j-1]中最长回文子序列长度的最大值。

填表顺序: 这里我们填dp[i][j]时用到了dp[i][j-1]dp[i+1,j]dp[i+1,j-1];那我们填表的顺序:从下到上,每一行从左到右。

**初始化:**我们在填第n-1行要用到第n行的数据、填写第1列时要用到第0列的数据,所以我们要初始化第n行和第0列。

**返回:**我们最后要的结果在dp[0][n-1]里存着(区间[0,n-1]内最长回文子序列的长度),最后输出dp[0][n-1]即可。

在这里插入图片描述

代码实现

#include <iostream>
using namespace std;
const int N = 1001;
int dp[N][N] = {0};
int main() {string str;cin>>str;for(int i = str.size()-1;i>=0;i--){for(int j = 0;j<str.size();j++){if(i>j)dp[i][j] = 0;else if(i == j)dp[i][j] = 1;else {if(str[i] == str[j])dp[i][j] = dp[i+1][j-1]+2;elsedp[i][j] = max(dp[i+1][j],dp[i][j-1]);}}}cout<<dp[0][str.size()-1]<<endl;return 0;
}

到这里本篇文章内容就结束了
感谢各位的支持

相关文章:

  • 线性回归之归一化(normalization)
  • Linux文件时间戳详解:Access、Modify、Change时间的区别与作用
  • MyBatis-Plus 分页功能详解
  • Jsp技术入门指南【九】详细讲解JSTL
  • 【英语语法】词法---动词
  • 【Linux】进程状态
  • JavaScript 一维数组转不含零的两个数
  • Keil MDK 编译问题:last line of file ends without a newline
  • 理解 React 的 useEffect
  • 线性回归之正则化(regularization)
  • Pandas数据可视化
  • 中科院:LRM在简单问题上缺失快思考能力
  • 抽象工厂模式及其在自动驾驶中的应用举例(c++代码实现)
  • Vivado中Tri_mode_ethernet_mac的时序约束、分析、调整——(五)调试注意的问题
  • Java编程基础(第一篇:变量)
  • prim最小生成树+最大生成树【C++】板子题
  • 【Sa-Token】学习笔记05 - 踢人下线源码解析
  • STM32嵌入式
  • JUC复习及面试题学习
  • OpenCV基础01-图像文件的读取与保存
  • 6万余采购商消博会上“扫货”,全球好物“购物车”满载而归
  • 恒安集团创始人许连捷逝世:白手起家缔造百亿纸品巨头,个人曾捐赠超10亿
  • 上海自然博物馆下月开启中国恐龙大展,还在筹备中国古人类大展
  • 上海浦东召开高水平改革开放推进会,综合型企业出海服务平台启动
  • 陈少洋出任中国航天科工集团党组副书记、董事、总经理
  • 山西婚约财产纠纷案二审宣判