CSDN竞赛15期题解

news/2024/11/30 0:43:58/

总结

CSDN竞赛越来越频繁了,这次竞赛比较简单,就当练习题了。

题目列表

1.求并集

题目描述

由小到大输出两个单向有序链表的并集 如链表 A {1 -> 2 -> 5 -> 7} 链表 B {3 -> 5 -> 7 -> 8} 输出: {1 -> 2 ->3 - > 5 -> 7 ->8} 。

输入描述:

第一行输入整数n,m,(1<=n,m<=1000)分别表示两个链表的长度。
第二行给出A链表所包含元素。(1<=a<=1000)
第三行给出B链表所包含元素。(1<=b<=1000)

输出描述:

按题目描述输出。

输入样例:

4 4
1 2 5 7
3 5 7 8

输出样例:

1 -> 2 ->3 -> 5 -> 7 ->8

分析

这道题作为面试题,考察链表比较合适,作为笔试题不太合适。一般的做法是使用类似于归并排序的合并算法,使用双指针来合并。但是完全没必要这么做,直接用一个数组读入,然后排下序就可以了。

当然,这题的用例告诉我们需要去重,所以可以读入一个set中,然后再排序就可以了。而实际上set已经默认排好序了,直接输出就可以了。

代码

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
set<int> s;
int main() {int n;int m;cin>>n>>m;vector<int> a;int x;for(int i = 0; i < n + m; i++) {cin>>x;s.insert(x);}for(auto t : s) {a.push_back(t);}int q = a.size();for(int i = 0; i < q - 1; i++) {cout<<a[i]<<" -> ";}cout<<a[q - 1]<<endl;return 0;
}

2.小T找糖豆

题目描述

已知连续序列A,包含1e18个元素,分别是[1,1e8]。 现在去除序列中的n个元素. 得到新的连续序列[X,1e8],该序列中 最小元素是?

分析

本题的题意是去掉若干元素后,求剩下连续序列的最小元素,用例给我们的感觉是必须是最后一个连续序列,所以相当于求出去除序列的最大值,加上1就是连续序列的最小元素了。

代码

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
int solution(int n, std::vector<int>& vec) {int res = 0;for(auto x : vec) {res = max(res, x);}return res + 1;
}
int main() {int n;std::vector<int> vec;std::cin>>n;std::string line_0, token_0;getline(std::cin >> std::ws,line_0);std::stringstream tokens_0(line_0);while(std::getline(tokens_0, token_0, ' ')) {vec.push_back(std::stoi(token_0));}int result = solution(n,vec);std::cout<<result<<std::endl;return 0;
}

3. 争风吃醋的豚鼠

题目描述

N个节点两两建边。 不存在3个节点相互之前全部相连(3个节点连接成环) 。最多能建立多少条边?

输入描述:

输入整数n.(1<=n<=1e5)

输出描述:

输出最大边数

输入样例:

4

输出样例:

4

分析

读完题目就知道肯定是有一个公式的,代码简洁,这类题目作为算法题不太合适,有点纯数学了。考试时想的是类似于二分图。我们将节点分为两组,两组节点之间互相全部连接上,组内节点不连接,这样添加任意一条边都会形成环,保证了边的最大值。

比如a,b,c,da,b,c,da,b,c,d四个点,a,ba,ba,b作为一组,c,dc,dc,d作为一组,连接ac,ad,bc,bdac,\ ad,\ bc,\ bdac, ad, bc, bd,构成的四条边不会形成环,同时边数是最大的。所以遍历下将nnn个节点划为两组节点的所有划法,取其中的边数最大值就可以了。

代码

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int main() {int n;std::cin>>n;ll res = 0;for(int i = 1; i < n; i++) {res = max(res,(ll)i * (n - i));}std::cout<<res<<std::endl;return 0;
}

4.题目名称:选择客栈

题目描述

丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。 两位游客一起去丽江旅 游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一 家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p 。 他们想 知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过 p 元的咖啡店小聚。

输入描述:

共n+1 行。
第一行三个整数 n ,k ,p ,每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;
接下来的 n 行,第 i+1 行两个整数,之间用一个空格隔开,分别表示 i 号客栈的装饰色调和 i 号客栈的咖啡店的最低消费。

输出描述:

一个整数,表示可选的住宿方案的总数。

输入样例:

5 2 3
0 5
1 3
0 2
1 4
1 5

输出样例:

3

分析

如果说前面题目出的不像算法题,那么这最后一题就有点坑了,第一个坑在于不给数据范围,但凡审题的同学认真点都不会不给数据范围,这种题目不给数据范围的话,我们是不方便选择合适复杂度的算法来求解的。

首先要考虑的是选择的两个客栈中间有没有合适的咖啡店,我们固然可以通过遍历来判断,但是复杂度高。这里可以使用前缀和来优化下,咖啡店的最低消费具体是多少我们不关注,如果不超过p,就是1,表示可以选择;超过了p,就是0,不能选择。然后对这个由0和1构成的数组求下前缀和s,就可以在O(1)的时间内判断两个客栈之间有没有合适的咖啡店了。

客栈iiijjj之间合适的咖啡店数是s[j]−s[i−1]s[j]-s[i-1]s[j]s[i1],只要这个值不是0,就表示我们可以选择i,ji,ji,j两个客栈住宿。

暴力的做法是二重循环枚举i,ji,ji,j,只要两家客栈色调相同,并且之间有合适的咖啡店,方案数就加一。时间复杂度是O(n2)O(n^2)O(n2),由于题目没有给定数据范围,所以可以提交下看看,发现TLE了,这就是本题的第二个坑,因为如果你在代码里面加上如果n>1e4n>1e4n>1e4的代码再提交就可以通过九成的用例了。这题用例的评测是一起了,最后一个用例TLE了,就一分没有,这点很不科学。

纯暴力的解法复杂度是立方级别的,前面使用前缀和优化掉一重循环,既然TLE了还需要继续优化。色调一共kkk种,虽然没有给数据范围,但是根据经验可以判定nnn的范围至少是10510^5105级别的,而kkk的范围一般不大。我们将所有的客栈根据色调不同按顺序分为kkk组,这样同一组内的客栈我们就不需要再考虑色调,只需要关心有没有合适的咖啡店就行了。问题就变成了在一个线性序列中,找到点对使得两点之间有合适的咖啡店了。

这里可以发现问题的单调性,比如一个人住在第一家客栈,第二个人从第二家客栈开始遍历,直到两家客栈之间有合适的咖啡店位置,从这家咖啡店到后面的所有客栈都可以住第二个人。然后第一个人住第二家客栈,第二个人不需要从第三家客栈遍历起,只需要从上次找到合适咖啡店的位置开始遍历就可以了,因为上次走过的客栈肯定都没有合适的咖啡店。这样一来,第二个人至多走完客栈一遍。如果某个色调序列的长度是q,那么在这个色调里面找两个合适客栈的复杂度就是O(q)O(q)O(q),遍历完k个色调序列的总的复杂度就是O(n)O(n)O(n)

不考虑本题的数据范围和用例评测的坑,这题考察了前缀和和双指针算法,一步步优化时间复杂度,题目质量还是不错的。

代码

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main() {int n;int k;int p;cin>>n>>k>>p;vector<int> c(n+1), a(n+1), s(n+1, 0);vector<int> m[k];for(int i = 1; i <= n; i++) {cin>>c[i]>>a[i];if (a[i] > p) a[i] = 0;else a[i] = 1;s[i] = s[i-1] + a[i];m[c[i]].push_back(i);}int res = 0;for(int t = 0; t < k; t++) {int q = m[t].size();for(int i = 0,j = 0; i < q; i++) {if(a[m[t][i]]) {res += q - i - 1;continue;} else {if(j > i) {res += q - j;continue;} else j = i + 1;while(j < q && !(s[m[t][j]] - s[m[t][i]-1])) j++;if(j < q) {res += q - j;} else {break;}}}}cout<<res<<endl;return 0;
}

http://www.ppmy.cn/news/3945.html

相关文章

小程序框架与生命周期

目录 框架 响应的数据绑定 页面管理 基础组件 丰富的 API 逻辑层 App Service 小程序的生命周期 注册页面 使用 Page 构造器注册页面 在页面中使用 behaviors 使用 Component 构造器构造页面 页面的生命周期 页面路由 页面栈 路由方式 注意事项 模块化 模块化…

【ROS话题通信】发布者和订阅者

前言 本文记录ROS话题通信的学习过程&#xff0c;便于后续复习。首先明确&#xff0c;ROS中的话题通信&#xff0c;在ROS通信中非常重要&#xff0c;实现了分布式发布接收消息&#xff0c;也是实现了不同编程语言间的解耦&#xff0c;下面记录下自己学习过程中的相关代码和配置…

【数据结构】树以及二叉树的概念

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《数据结构》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 树的概念&#xff1a; 树的相关概念&#xff1a; 树如何表示&#xff…

Docker入门(基础篇)

Docker入门Docker相关概念为什么需要DockerDocker的理念容器与虚拟机的比较Docker的安装与使用安装Dockerdocker 的三要素Docker常用命令Docker相关概念 为什么需要Docker 为什么会出现Docker了&#xff1f;现在我们假设你在开发一个项目&#xff0c;你使用的是一台笔记本电脑…

Windows 下 MongoDB 6 详细安装教程(图文结合)

​ MongoDB是一个基于分布式文件存储 [1] 的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 ​ MongoDB是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。它支持的数据结构非常…

PyTorch笔记 - ResNet: Deep Residual Learning for Image Recognition

欢迎关注我的CSDN:https://blog.csdn.net/caroline_wendy 本文地址:https://blog.csdn.net/caroline_wendy/article/details/128341408 Paper:ResNet - Deep Residual Learning for Image Recognition Kaiming He,Microsoft Research工程:TIMM,https://github.com/rwight…

Java——布隆过滤器

在上一篇博客中讲到位图是用来判定一个正整数是否存在的。对于一个负数&#xff0c;我们可以统一规定让他们加上一个数&#xff0c;变成正数&#xff0c;然后用位图的方式存储。但是对于字符串&#xff0c;我们就没办法存储了。因此发明了布隆过滤器 概念 对于网络上很多需要…

[附源码]Python计算机毕业设计高校学生管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…