【编程笔试】美团2021校招笔试-通用编程题第2场(附思路及C++代码)

2023-11-04

练习地址

点此前往练习

小团的配送团队

小团是美团外卖的区域配送负责人,众所周知,外卖小哥一般都会同时配送若干单,小团在接单时希望把同一个小区的单子放在一起,然后由一名骑手统一配送。但是由于订单是叠在一起的,所以,他归类订单时只能知道新订单和已有的某个订单的小区是相同的,他觉得这样太麻烦了,所以希望你帮他写一个程序解决这个问题。

即给出若干个形如a b的关系,表示a号订单和b号订单是同一个小区的 ,请你把同一个小区的订单按照编号顺序排序,并分行输出,优先输出最小的订单编号较小的小区订单集合。订单的编号是1到n。(可能存在同时出现a b和b a这样的关系,也有可能出现a a这样的关系)

输入描述:

输入第一行是两个正整数n,m,表示接受的订单数量和已知的关系数量。(1<=n,m<=10000)接下来有m行,每行两个正整数a和b,表示a号订单和b号订单属于同一个小区(1<=a,b<=n);

输出描述:

输出第一行包含一个整数x,表示这些订单共来自x个不同的小区。接下来的输出包含x行,每行表示输出若干个订单编号,表示这些订单属于同一个小区,按照订单编号升序输出。优先输出最小的订单编号较小的小区。

输入例子1:

5 5

1 2

2 2

3 1

4 2

5 4

输出例子1:

1

1 2 3 4 5

思路:

根据题意,考虑使用并查集。

注意输出需要输出集合的个数,对所有的订单遍历,查找属于同一个集合中的元素,放入vector容器中。

代码:

#include<bits/stdc++.h>
#define N 10010
using namespace std;

int pa[N];
vector<int> g[N];
//并查集的初始化
void init(int n)
{
	for(int i = 0;i<=n;i++)
	{
		pa[i]=i;
	}
}
//并查集的查找:在x所在的集合中查找集合编号 
int find(int x) 
{
	if(x!=pa[x])
		pa[x]=x=find(pa[x]);
	return pa[x];
} 
//并查集的合并:将x和y所在的集合合并
void merge(int x,int y)
{
	x = find(x);
	y = find(y);
	if(x!=y)
	{
		if(x<y)
			pa[y]=x;
		else
			pa[x]=y;
	}
}
 
int main()
{
	int n,m,a,b;
	cin>>n>>m;
	init(n);
	for(int i=0;i<m;i++)
	{
		cin>>a>>b;
		merge(a,b);
	}
	int count = 0;
	for(int i = 1;i<=n;i++)
	{
		if(pa[i]==i)
			count++;
		int pi=find(i);
		g[pi].push_back(i);
	}
	cout<<count<<endl;
	for(int i=1;i<=n;i++)
	{
		if(pa[i]==i)
		{
			for(auto x:g[i])
				cout<<x<<" ";
			cout<<endl;
		}
	}
	return 0;
}

不一样的逆序数

小团最近对逆序数(将一个数字逐位逆序,例如1234的逆序数为4321,1100的逆序数为11)特别感兴趣,但是又觉得普通的逆序数问题有点太乏味了。

于是他想出了一个新的定义:如果一个数的4倍恰好是它的逆序数,那么称这两个数是新定义下的逆序对。

接下来给定一正整数n,问:不超过n的正整数中有多少对新定义下的逆序对?

输入描述:

单组输入。输入一个正整数n,n<1e7

输出描述:

第一行输出在不超过n的前提下有多少对逆序数,接下来每一行输出一对逆序数,以空格分隔。如果有多组逆序数,按照第一个数升序输出。如果没有一对逆序数则直接输出0即可。

输入例子1:

10000

输出例子1:

1
2178 8712

思路:

使用穷举法遍历查找满足要求的逆序数。

输出通过pair定义一个数据对,当找到满足要求的逆序数对后,将它们存放在vector容器中,计数+1。

代码:

#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> Reverse;
//获取逆序数 
int get(int num)
{
	int reverse=0;
	while(num)
	{
		reverse = reverse*10+num%10;
		num/=10;
	} 
	return reverse;
}

int main()
{
	int n;
	cin>>n;
	vector<Reverse> nums;
	int count=0;
	for(int i=1;i<=n;i++)
	{
		int reverse = get(i);
		if(reverse<=n&&reverse==i*4)
		{
			nums.push_back({i,reverse});
			count++;
		}
	}
	cout<<count<<endl;
	for(auto x :nums)
		cout<<x.first<<" "<<x.second<<endl;
	return 0;
}

小团的旅行路线

小团是一个旅游爱好者,快要过春节了,他想统计一下,在过去的一年中他进行过几次旅行,于是他打开了美团app的订单记录,记录显示了他的购买车票的记录。记录是按时间顺序给出的,已知一次旅行的线路一定是一个闭环,即起点和终点是同一个地点。因此当每找到一段闭合的行程,即认为完成了一次旅行。数据保证不会出现不在闭环路径中的数据。

请你在小团的购票记录中统计出他全年共进行了多少次旅行?

输入描述:

输入第一行包含一个正整数n,表示小团的购票记录数量。(1<=n<=10000)接下来有n行,每行是两个长度不超过10的仅由小写字母组成的字符串S_a S_b,表示购买了一张从S_a到S_b的车票。

输出描述:

输出仅包含一个整数,表示小团的旅行次数。

输入例子1:

6

beijing nanjing

nanjing guangzhou

guangzhou shanghai

shanghai beijing

fuzhou beijing

beijing fuzhou

输出例子1:

2

思路:

利用题设:起点和终点是同一个地点。当满足该条件时,计数+1。

代码:

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	cin>>n;
	string a,b,start="";
	int count=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a>>b;
		if(start=="")
		{
			start=a;
		}
		if(b==start)
		{
			count++;
			start="";
		}
	}
	cout<<count<<endl; 
	return 0;
}

小团的车辆调度

小团是美团汽车租赁公司的调度师,某个时刻A和B两地都向该公司提交了租车的订单,分别需要a和b辆汽车。此时,公司的所有车辆都在外运营,通过北斗定位,可以得到所有车辆的位置,小团分别计算了每辆车前往A地和B地完成订单的利润。作为一名精明的调度师,当然是想让公司的利润最大化了。

请你帮他分别选择a辆车完成A地的任务,选择b辆车完成B地的任务。使得公司获利最大,每辆车最多只能完成一地的任务。
输入描述:

输入第一行包含三个整数n,a,b,分别表示公司的车辆数量和A,B两地订单所需数量,保证a+b<=n。(1<=n<=2000)接下来有n行,每行两个正整数x,y,分别表示该车完成A地任务的利润和B地任务的利润。

输出描述:

输出仅包含一个正整数,表示公司最大获得的利润和。

输入例子1:

5 2 2

4 2

3 3

5 4

5 3

1 5

输出例子1:

18

思路:

根据题意,可以抽象成0/1背包问题,考虑使用滚动数组优化的动态规划法。

设dp[i][j][k]表示第i辆车,则可以得到如下转移式:

d p [ i ] [ j ] [ k ] = m a x { d p [ i − 1 ] [ j − 1 ] [ k ] + A [ i ] , d p [ i − 1 ] [ j ] [ k − 1 ] + B [ i ] , d p [ i − 1 ] [ j ] [ k ] } dp[i][j][k]=max\{dp[i-1][j-1][k]+A[i],dp[i-1][j][k-1]+B[i],dp[i-1][j][k]\} dp[i][j][k]=max{dp[i1][j1][k]+A[i],dp[i1][j][k1]+B[i],dp[i1][j][k]}

同时考虑合法状态,对于每一个合法状态dp[i][j][k],必定会有i≥j+k。所以在转移前需要考虑是否能够转移。

下述代码只过了4/10组用例,AC代码详见评论区

代码:

#include<bits/stdc++.h>
#define N 1010
using namespace std;

int dp[2][N][N];
int A[N],B[N];
int main()
{
	int n,a,b;
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++)
	{
		cin>>A[i]>>B[i];
	}
	for(int i=1;i<=n;i++)
	{
		dp[i%2][1][0]=A[i];
		dp[i%2][0][1]=B[i];
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k+j<=i;k++)
			{
				dp[i%2][j][k]=max(dp[(i-1)%2][j-1][k]+A[i],dp[(i-1)%2][j][k-1]+B[i]);
				if(i-1>=j+k)
					dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i-1)%2][j][k]);
			}
		}
	}
	cout<<dp[n%2][a][b];
	return 0;
}

总结

第一题:

  1. 并查集模板:
#define N 10010

int pa[N];
//并查集的初始化
void init(int n)
{
	for(int i = 0;i<=n;i++)
	{
		pa[i]=i;
	}
}
//并查集的查找:在x所在的集合中查找集合编号 
int find(int x) 
{
	if(x!=pa[x])
		pa[x]=x=find(pa[x]);
	return pa[x];
} 
//并查集的合并:将x和y所在的集合合并
void merge(int x,int y)
{
	x = find(x);
	y = find(y);
	if(x!=y)
	{
		if(x<y)
			pa[y]=x;
		else
			pa[x]=y;
	}
}
  1. for(auto i : v)遍历容器元素:C++11的新特性。
    1. v是一个可遍历的容器或流,比如vector类型,i就用来在遍历过程中获得容器里的每一个元素。
    2. 等价于for(some_iterator it = v.begin(); it != v.end(); ++it)some_type i = *it
    3. 另外还可以是for(auto**&** i : v),for(auto**&&** i: v),区别在于i是值还是引用。

第二题:

  1. 获取一个数的逆序数:
//获取逆序数 
int get(int num)
{
	int reverse=0;
	while(num)
	{
		reverse = reverse*10+num%10;
		num/=10;
	} 
	return reverse;
}
  1. 输出是数据对时,可通过pair定义一个数据对,再使用vec.push_back(Pair)将其存放入vector容器中。

    • pair:将2个数据组合成一组数据。

      • 头文件#include <utility>
      • 创建空的pair对象:pair<T1, T2> p;
      • 以v1和v2的值创建pair对象:make_pair(v1, v2);
      • pair对象的比较运算:p1 op p2;op是比较运算符>或<,遵循字典次序。
      • pair对象的相等:p1 == p2;p1和p2的first和second依次相等。
      • 返回pair对象中第一个公有数据成员:p.first;
      • 返回pair对象中第二个公有数据成员:p.second;
      • 在某些清况函数会以pair对象作为返回值时,可以直接通过std::tie进行接收。
    • C++ vector中使用pair:

      • 声明vector:vector< pair<T1,T2> > vec;注意:vector<> 与里面的pair<T1,T2>得有间隔,否则会报错,编译器会识别成>>运算符的重载。

      • 向vector中插入pair数据:vec.push_back(make_pair<T1,T2>(a,b));

      • 定义迭代器:

        vector<pair<int,int> > ::iterator iter;
        for(iter=vec.begin();iter!=vec.end();iter++);
        
      • 数据读取:
        第一个数据:(*iter).first
        第二个数据:(*iter).second

第三题:

暂无

第四题:

  1. 动态规划(DP)解决0/1背包问题:

    • 背包容量不足以装入物品i,则装入前i个物品得到的最大价值和装入前i-1个物品得到的最大价值是相同的;
    • 背包容量可以装入物品i,如果把第i个物品装入背包,则背包中物品的价值等于把前i-1个物品装入容量为j-wi的背包中的价值加上第i个物品的价值vi;如果第i个物品没有装入背包,则背包中物品的价值等于把前i-1个物品装入容量为j的背包中所取得的价值。取二者中的较大者作为把前i个物品装入容量为j的背包中的最优解。
    • 递推式:

V ( i , j ) = { V ( i − 1 , j ) j < w i m a x { V ( i − 1 , j ) , V ( i − 1 , j − w i ) + v i } j ≥ w i V(i,j)=\left\{ \begin{array}{lr} V(i-1,j)&j<w_i\\ max\{V(i-1,j),V(i-1,j-w_i)+v_i\}&j≥w_i \end{array} \right. V(i,j)={V(i1,j)max{V(i1,j),V(i1,jwi)+vi}j<wijwi

  1. 滚动数组优化动态规划的空间

    二维数组例子:

    int i, j, d[100][100];
    for(i = 1; i < 100; i++)
        for(j = 0; j < 100; j++)
            d[i][j] = d[i - 1][j] + d[i][j - 1];
    

    由于d[i][j]只依赖于d[i - 1][j], d[i][j - 1],因此使用滚动数组实现如下:

    int i, j, d[2][100];
    for(i = 1; i < 100; i++)
        for(j = 0; j < 100; j++)
            d[i % 2][j] = d[(i - 1) % 2][j] + d[i % 2][j - 1];
    

    此处%2也可以用&1。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【编程笔试】美团2021校招笔试-通用编程题第2场(附思路及C++代码) 的相关文章

  • jQuery qTip2提示插件 (示例图,API)

    author YHC 首先介绍一下 主要的作用 用作网页中的提示 例如新手入门的导航 看下图你就明白了 当然这个插件在提示上功能非常丰富 下面主要介绍下载地址 以及入门的一个最小的 例子 qTip2官网下载地址 qTip2官网推荐下载地址
  • Android webView去除默认边框

    Android WebView无论怎么修改它的属性都会存在一定的边距 这是因为 HTML 的 body 标签默认存在一定边距 修改 webView 的属性并没有作用 解决办法 修改 html 代码 html data 原本需要加载的html
  • KaTeX

    KaTeX LaTeX数学公式编辑手册 只需要在第三列写法前后分别加上 就可以转换为符号 但需注意 CSDN的使用的是 KaTeX KaTeX KATE X数学公式 而不是 LaTeX LaTeX LATE X 两者会有些许区别 如果有
  • 漂亮的计算器页面 html,html+css实现一个好看的计算器实例代码

    最终效果如下图 2 有bug 就是整数后点击 号结果正确 如果小数后面点击 的话结果就错误 其他都正常 求指点 input的value是string类型的 在JS中改如何正确处理下图 1中的if部分 图 1 图 2 HTML代码如下 简单的
  • 【超全汇总】学习数据结构与算法,计算机基础知识,看这篇就够了

    由于文章有点多 并且发的文章也不是一个系列一个系列发的 不过我的文章大部分都是围绕着 数据结构 算法 计算机网络 操作系统 Linux 数据库 这几个方面发的 为了方便大家阅读 我整理了一波 不过公众号可以说是不支持修改文章 因为我决定每两
  • Java环境从删除到重装

    Java环境从删除到重装 前言 须知 如何完全删除jdk 安装jdk 前言 今天由于一些原因把Java环境删除了 怎么装都装不好 遇到了很多错误 在网上找了好多解决办法之后终于弄好了 所以写成一份Java环境从删除到重装 给各位不小心删除J

随机推荐

  • Centos7下基于jdk11 安装RocketMQ

    1 简介 RocketMQ是阿里巴巴中间件团队自研的一款高性能 高吞吐量 低延迟 高可用 高可靠 具备金融级稳定性 的分布式消息中间件 开源后并于2016年捐赠给Apache社区孵化 目前已经成为了 Apache顶级项目 当前在国内被广泛的
  • 用html+js实现代码背景墙特效【建议收藏】

    在csdn里面 有些博主的主页非常的帅 就是代码从上往下掉的特效 那么这种效果我们作为程序员该如何去写出来呢 不用担心 这篇博客就分享如何创建一个代码背景墙 1 效果展示 2 代码分享
  • java.io.FileNotFoundException: http://www.xxxxx.net:8080/test/test/ 403错误

    POST请求错误内容 java io FileNotFoundException http www xxxxx net 8080 test test at libcore net http HttpURLConnectionImpl get
  • python 中的六种“复制”方法

    以列表为例 方法一 直接变量赋值 将 li 赋值给变量 li1 打印他们的id会发现 他们的id是一样的 即是 li 和 li1 这两个变量在python中是同一个内存地址 对他们任何一个变量进行修改 另外一个会跟着变化 li 1 2 3
  • arm体系结构概述和编程模型

    1 arm体系结构的版本 1 arm1 6 2 arm体系的变种 1 T 系列 Thumb指令集 可以支持Thumb指令集 2 M系列 支持长乘法 32位 32位生成64位数据 长乘加指令 再加上32位数据 3 E系列 增强型DSP指令 增
  • 【Go语言(golang)教程】A Tour of Go 七十集大全

    http www aqee net go a tour of go 5 Go语言 golang 教程 A Tour of Go 1 Hello World Go语言 golang 教程 A Tour of Go 2 安装离线练习器 Go语言
  • 数字电子钟 1Hz 秒脉冲信号的设计

    数字电子钟 1Hz 秒脉冲信号的设计 摘 要 要设计数字钟 首先应选择一个能产生稳定的标准时间脉冲信号 而脉冲源产生的脉冲信号的频率较高 因此 需要进行分频 使高频脉冲信号变成适合于计时的低频脉冲信号 即 秒脉冲信号 频率1HZ 1引言 数
  • 找出看了5个电影以上的用户

    问题 在1亿条用户记录里 如何快速查询统计出看了5个电影以上的用户 解答 分以下几个步骤完成 1 建立 hash map lt 用户 电影数 gt 2 顺序扫描1亿条用户记录 1 如果 用户 在hash map中不存在 则新增并设 电影数
  • IT项目管理之第5章 项目时间管理习题之案例分析汇总

    IT项目管理之第5章 项目时间管理习题之案例分析汇总 项目时间管理习题之案例分析汇总 案例1 案例分析 案例1参考答案 案例2 案例2分析 案例2参考答案 叮嘟 这里是小啊呜的学习课程资料整理 好记性不如烂笔头 今天也是努力进步的一天 一起
  • DevopsCamp 第 2 期作业: 《cobra - 05 Go 项目的目录结构》

    DevopsCamp 第 2 期作业 cobra 05 Go 项目的目录结构 原文链接 https typonotes com posts 2023 02 13 devopscamp cobra 05 layout Go 项目的目录结构 G
  • windows server 2016搭建AD域

    此实验以windows sever 2016为例 安装windows server 2016 操作省略 一台服务器想要安装成AD DC 活动目录域服务 必须具备以下条件 安装者必须具有本地管理员权限 DNS基础结构的支持 可以在安装AD D
  • 电脑开机出现黑屏,出现“windows 未能启动,原因可能更改了硬件或者软件,解决此类问题的步骤”

    出现问题的界面如下 解决此类问题的步骤如下 1 直接按 enter 回车键 2 出现以下界面 我自己的是windows 10系统哈 因为当时没保存自己的照片 只能拿这个顶替一下 但是步骤是一样的 3 然后按提示按F8 正常来说时会出现以下的
  • Python高级函数2:使用itertools、functools、operator使得代码更高效、可读、可重用

    Python高级函数2 使用itertools functools operator使得代码更高效 可读 可重用 1 原理 itertools groupby functools partial operator attrgetter 和
  • python生成gif(图片渐变)

    show you the code 后面还需要完善图片分辨率的处理 这样就比较好了 目前分辨率没有进行处理 import os import imageio from PIL import Image from images2gif imp
  • 【python】IPython的使用技巧整理

    IPython是一种基于Python的交互式解释器 提供了强大的编辑和交互功能 IPython拥有 满足你各种需求的交互式shell 火爆数据科学社区的Jupyter内核 供Jupyter Notebook使用 对交互式数据可视化和GUI工
  • Cocos2d-X3.0版的HelloWorld工程分析

    打开上一篇博客中的HelloWorld工程后 会看到下图所示的工程文件 main cpp文件中的代码 本人已经注释 1 2 3 4 5 6 7 8 9
  • MATLAB2016笔记(十):曲线拟合、参数估计

    文章目录 一 曲线拟合函数 一 概述 二 多项式拟合 polyfit 三 加权最小方差 WLS 拟合 自行编写polyfits 四 非线性曲线拟合 lsqcurvefit 二 参数估计函数 一 常见分布的参数分布 二 点估计 最大似然估计
  • Puppeteer入门初探

    本文来自网易云社区 作者 唐钊 最近在看 node 爬虫相关的一些东西 我记得还是很久以前常用的 node 爬虫工具还是 superagengt cherrio 他们的思路是通过发起 http 请求然后截取 respone 的内容 但是随着
  • Vue集成百度的Ueditor 前端+后台

    1 vue安装命令 npm i vue ueditor wrap 2 下载插件 Ueditor官网地址为 Ueditor 3 插件位置 下载好之后 将Jsp版本解压 解压后文件夹改名为UEditor 将文件夹中的 jsp目录删掉 将UEdi
  • 【编程笔试】美团2021校招笔试-通用编程题第2场(附思路及C++代码)

    导览 练习地址 小团的配送团队 不一样的逆序数 小团的旅行路线 小团的车辆调度 总结 练习地址 点此前往练习 小团的配送团队 小团是美团外卖的区域配送负责人 众所周知 外卖小哥一般都会同时配送若干单 小团在接单时希望把同一个小区的单子放在一