美团2024年春招第一场笔试 C++

目录

1,小美的平衡矩阵

2,小美的数组询问

3,小美的MT

 4,小美的朋友关系


1,小美的平衡矩阵

 【题目描述】

给定一个n*n的矩阵,该矩阵只包含数字0和1。对于 每个i(1<=i<=n),求在该矩阵中,有多少个i*i的区域满足0的个数等于1的个数???

【题目解析】

示例演示:

 如上图,1*1的区域结果为0,2*2的区域结果为7。

算法:前缀和+遍历

题目中给的数据范围是n<=200,所以可以直接遍历数组。

维护 一个前缀和数组统计以(x,y)这个点为右下角,以(1,1)这个点为左上角,这个区域中所有元素的和,由于数组中的数要么是0,要么是1,所以前缀和就表示某个区域中1的个数。

有了前缀和数组,就可以快速 求出某个区域中1的个数,如图:

而这个区域的大小我们是知道的,假设是k,那么这个区域的元素个数就是k*k。如果满足这个区间中1的个数等于k*k/2,那么说明 这个区间中0和1的个数 相等。而1的个数我们可以通过前缀和来表示。

同时还有一点,如果k为奇数,那么k*k的区域中元素个数一定为奇数 ,所以0和1的个数一定不相等。直接输出0即可。

 注意:在输入数据的时候,如果是以整数的形式接受,那么不建议使用cin,因为cin会把第一行的所有数据读成一个整数。就比如 上面的示例,第一行会被读成一个整数1010,而我们期望是读到4个整数的,这是可以使用scanf("%1d",&a),使用 %1d占位符可以确保读到的第一行是4个整数。

【代码】

#include <iostream>
#include <vector>
using namespace std;const int N = 205;
int arr[N][N], s[N][N];
//s为前缀和数组
//统计矩形(1,1)到(n,n)中1的数量int main()
{int n = 0;cin >> n;for(int  i=1;i<=n;i++)for (int j = 1; j <= n; j++){scanf("%1d", &arr[i][j]);s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + arr[i][j];}cout << 0 << endl;for (int k = 2; k <= n; k++){if (k & 1){cout << 0 << endl;continue;}int ans = 0;for(int i=1;i+k-1<=n;i++)for (int j = 1; j+k-1 <= n; j++){//(i,j)是左上角,需要我们计算出k*k这个区域右下角的坐标int x = i + k - 1;int y = j + k - 1;if (s[x][y] - s[i - 1][y] - s[x][j - 1] + s[i - 1][j - 1] == k * k / 2)ans++;}cout << ans << endl;}return 0;
}

2,小美的数组询问

 直接遍历即可 

#include <iostream>
using namespace std;const int N=1e5+10;
int arr[N];
int main()
{int n=0,q=0;cin>>n>>q;long long sum=0,count=0;for(int i=1;i<=n;i++){cin>>arr[i];sum+=arr[i];if(arr[i]==0)count++;}int l,r;while(q--){cin>>l>>r;cout<<sum+count*l<<" "<<sum+count*r<<endl;}return 0;
}

3,小美的MT

统计元字符中 有多少个M和T,再加上最多可以修改 多少个即可。

//小美的MT
#include <iostream>
#include <string>
using namespace std;int main()
{int n = 0, k = 0;cin >> n >> k;string str;cin >> str;int ans = 0;for (int i = 0; i < n; i++){if (str[i] == 'M' || str[i] == 'T')ans++;}if (k > n - ans)cout << n << endl;elsecout << ans + k << endl;return 0;
}

 4,小美的朋友关系

 【题目描述】

总人数为n,编号u和v的人之间存在朋友关系,在这n个人中,存在m个朋友关系。

对于这些关系,进行q次事件,格式为【op,u,v】,其中u和v表示人的编号。op表示要进行哪种操作,当op==1时,u和v的朋友关系淡忘,也就是断开u和v的朋友关系。当op==2时,表示查询u和v是否可以建立朋友关系,可以通过第三方或者本来就是朋友关系。

针对每次的op==2操作,返回一个结果Yes or No,表示是否可以建立朋友关系 。

【思路】

这n个人中存在许多的朋友关系,比如编号1-5是朋友,编号6-10是朋友,这两个关系是独立的集合,所以可以想到的是使用并查集来记录朋友关系。

并查集传送门:

【算法与数据结构】并查集详解+题目_并查集结构体-CSDN博客

 并查集中的每个集合可以看成是一棵树,独立多个集合,就是多个独立的树。每个树的根节点也就是每个集合的父节点。


刚开始我的思路是将这m个朋友关系,使用并查集来存储。

但是在q次操作中,op=2是查询是否可以 建立朋友关系的操作,这个简单,只需判断这两个人是否在同一个集合中,也就是这两个人的父节点是否相同。但是对于op=1删除朋友关系操作,比较困难,因为并查集擅于进行 添加关系操作的,不好处理删除节点关系所以在删除朋友关系这里出现了问题。

我们可以试着把删除朋友关系变成添加朋友关系。这样并查集就可以做了。那么怎么实现呢?

我们可以先将这m个朋友关系用特定的容器存储下来,首先遍历q次操作,遇到删除操作(u,v),在容器中删除(u,v)。

注意:这里删除的时候,要删除的朋友关系是(u,v),有可能存储的时候,朋友关系是(u,v),也有可能是(v,u),这些都是要删除的。

遇到op=2时,不进行操作。一次操作完成后,将该次操作用数组记录下来【op,u,v】。


顺序遍历完后,此时将容器中剩余的朋友关系,构建并查集。 然后逆序遍历记录操作的数组,遇到op=1时,就添加朋友关系,遇到op=2时,就查询朋友关系,判断父节点是否相等即可。

 【代码】

//小美的朋友关系
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int N = 1e5;//总人数,初始的朋友关系数,事件数量
int n, m, q;
vector<int> parent;//并查集
set<pair<int, int>> st;//存储初始的朋友关系
//存储事件
struct node
{int op, u, v;
}arr[N+5];
//找父节点,路径压缩
int find(int x)
{if (parent[x] != x)parent[x] = find(parent[x]);return parent[x];
}
//合并
void unite(int x, int y)
{int rootX = find(x);int rootY = find(y);if (rootX == rootY)return;parent[rootX] = rootY;
}
int main()
{cin >> n >> m >> q;//初始化并查集parent.resize(n + 1);for (int i = 1; i <= n; i++)parent[i] = i;//存储关系int op,u, v;while (m--){cin >> u >> v;st.insert({ u,v });}int num = 0;while (q--){cin >> op >> u >> v;//处理删除操作if (op == 1){if (st.find({ u,v }) != st.end())st.erase({ u,v });else if (st.find({ v,u }) != st.end())st.erase({ v,u });elsecontinue;//说明u和v表示朋友关系,此次删除操作无意义,不需要存储下来}//记录操作arr[num++] = { op,u,v };}//删除关系完成后,剩余的元素是没有进行操作的//构建并查集for (auto [u, v] : st)unite(u, v);vector<bool> ans;//记录最终结果//逆序遍历操作//如果是删除就进行合并//如果是查询就进行判断是否在同一个集合for (int i = num - 1; i >= 0; i--){op = arr[i].op, u = arr[i].u, v = arr[i].v;if (op == 1){//合并unite(u, v);}else{//判断ans.emplace_back(find(u) == find(v));}}for (int i = ans.size() - 1; i >= 0; i--)if (ans[i])cout << "Yes" << endl;elsecout << "No" << endl;return 0;
}

上述代码是使用vector来实现并查集的,题目中的数据范围n是1e9,如果使用vector,就需要开辟1e9个空间,会超出内存限制。所以这里实现并查集的时候,需要使用map来替代。存储当前节点和它的父节点。具体原因,看下方:

初始时,每个节点的父节点就是自己本身。比如mp[1]=1。


当我们逆序遍历时,当遇到op=2,查询朋友关系时,给的两个朋友编号u和v,之前可能没初始化。比如n=10,给了3个朋友关系(1,3),(3,2),(4,6),当我们查询的时候,可能查询的是(5,7),这两个节点没有初始化,也就是mp[5]=0,mp[7]=0,可以发现这两个节点的父节点都是0,如果直接判断,得到的结果是可以构成朋友关系,但本质是不能构成朋友关系的。


也可以看下方代码的初始化部分,我们只初始化了存在朋友关系的节点,其他的节点没有初始化,他们的父节点默认就是0。如果我们开始将所有节点都初始化好,那么就会超出内存限制,那么就和使用vector一样了,甚至占用的内存比vector还要大,所以我们不能一次性就初始还所有节点。而是当遇到一个没初始化的节点,就初始化即可。


所以在查询操作的时候,如果mp[u]=0,或者mp[v]=0,就把这两个值做一下初始化mp[u]=u或者mp[v]=v,这样在判断的时候就不会出错了。


而如果使用的是vector来表示并查集,是不需要考虑这个问题的,因为vector会开辟n个空间,将所有人都初始化好,父节点就是自己。而使用map来存储,只会存储存在朋友关系的节点,如果出现一个新的节点,需要我们自己再初始化。这也就是map不会超出内存限制而vector会超出内存限制的原因

 【代码】

//小美的朋友关系
#include <iostream>
#include <vector>
#include <map>
#include <set>
using namespace std;
const int N = 1e5;//总人数,初始的朋友关系数,事件数量
int n, m, q;
map<int,int> parent;//并查集
set<pair<int, int>> st;//存储初始的朋友关系//存储事件
struct node
{int op, u, v;
}arr[N + 5];
//找父节点,路径压缩
int find(int x)
{if (parent[x] != x)parent[x] = find(parent[x]);return parent[x];
}
//合并
void unite(int x, int y)
{int rootX = find(x);int rootY = find(y);if (rootX == rootY)return;parent[rootX] = rootY;
}
int main()
{cin >> n >> m >> q;//初始化并查集和关系集合int op, u, v;for (int i = 0; i < m; i++){cin >> u >> v;parent[u] = u;parent[v] = v;st.insert({ u,v });}int num = 0;while (q--){cin >> op >> u >> v;//处理删除操作if (op == 1){if (st.find({ u,v }) != st.end())st.erase({ u,v });else if (st.find({ v,u }) != st.end())st.erase({ v,u });elsecontinue;//说明u和v表示朋友关系,此次删除操作无意义,不需要存储下来}//记录操作arr[num++] = { op,u,v };}//删除关系完成后,剩余的元素是没有进行操作的//构建并查集for (auto [u, v] : st)unite(u, v);vector<bool> ans;//记录最终结果//逆序遍历操作//如果是删除就进行合并//如果是查询就进行判断是否在同一个集合for (int i = num - 1; i >= 0; i--){op = arr[i].op, u = arr[i].u, v = arr[i].v;if (op == 1){//合并unite(u, v);}else{//parent[u]==0,说明该节点第一次出现,初始化为uif (parent[u] == 0)parent[u] = u;if (parent[v] == 0)parent[v] = v;//判断ans.emplace_back(find(u) == find(v));}}for (int i = ans.size() - 1; i >= 0; i--)if (ans[i])cout << "Yes" << endl;elsecout << "No" << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/80240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

09-DevOps-Jenkins实现CI持续集成

前面已经把harbor搭建好了&#xff0c;也可以向harbor中推送自定义镜像。 原计划是在Jenkins这台服务器上&#xff0c;完成镜像构建&#xff0c;然后把镜像推送的harbor仓库中。现在改变计划了&#xff0c;Jenkins所在的服务器&#xff08;192.168.1.10&#xff09;不负责镜像…

Postman设置了Cookies但是请求不携带Cookie

1 问题说明 使用Postman工具往往要向本地服务器发送请求携带Cookie便于测试接口&#xff0c;但是在Send下面的Cookies选项中设置域名127.0.0.1&#xff0c;并添加Cookie&#xff0c;发现发送的请求怎么都不会携带Cookie&#xff1a; 通过Fiddler抓包发现并没有Cookie&#xff1…

【unity】Vulkan模式下部分Android机型使用VideoPlayer组件播放视频异常问题

一、问题背景 考虑到Vulkan高性能的优势&#xff0c;项目组决定打包设置为vulkan优先&#xff0c;opengl es次之的方案&#xff1b;但由于部分低端设备或者部分模拟器对Vulkan的兼容性良莠不齐&#xff0c;导致诸如使用VideoPlayer组件无法正常播放视频等问题频发&#xff0c;而…

0802api设计和实战-网络ajax请求1-react-仿低代码平台项目

文章目录 1 API设计1.1 用户功能1.1.1 获取用户信息1.1.2 注册1.1.3 登录 1.2 问卷功能1.2.1 获取单个问卷1.2.2 获取问卷列表1.2.3 创建问卷1.2.4 更新问卷1.2.5 批量彻底删除问卷1.2.6 复制问卷 1.3 小结 2 实战2.1配置axios2.2 封装API和测试2.3 新建问卷2.4 自定义hooks封装…

Android Kotlin AIDL 完整实现与优化指南

本文将详细介绍如何在Android中使用Kotlin实现AIDL&#xff08;Android Interface Definition Language&#xff09;&#xff0c;并提供多种优化方案。 一、基础实现 1. 创建AIDL文件 在src/main/aidl/com/example/myapplication/目录下创建&#xff1a; IMyAidlInterface.…

【数据结构】_栈和队列相关面试题

&#x1f525; 数据结构修炼场 &#x1f525; &#x1f4a5; 栈与队列 终极试炼 &#x1f4a5; &#x1f680; 理论已加载完毕&#xff0c;代码之魂觉醒时刻&#xff01; ⚡️ 是时候用实战点燃你的算法之力了—— 「题目风暴&#xff0c;来袭&#xff01;」 &#xff08;握…

精益数据分析(8/126):从Airbnb案例看精益创业与数据驱动增长

精益数据分析&#xff08;8/126&#xff09;&#xff1a;从Airbnb案例看精益创业与数据驱动增长 大家好&#xff01;一直以来&#xff0c;我都坚信在创业和技术的领域里&#xff0c;持续学习与分享是不断进步的关键。今天&#xff0c;咱们继续深入学习《精益数据分析》&#x…

专题二十:路由策略与策略路由

一、路由策略 1.1 路由策略的概念 路由策略是通过修改路由表的路由条目来控制数据流量的可达性。即对接受和发布的路由进过滤。这种方式称为路由策略 路由策略功能相关作用控制路由的发布可通过路由策略对所要发布的路由信息进行过滤&#xff0c;只允许发布满足条件的路由信…

VSCode 扩展离线下载方法

学习自该文章&#xff0c;感谢作者&#xff01; 2025 年 VSCode 插件离线下载攻略&#xff1a;官方渠道一键获取 - 知乎 获取扩展关键信息 方法一&#xff1a;官网获取 打开 VSCode 扩展官方网站 搜索要下载的扩展&#xff0c;以 CodeGeeX 为例&#xff0c;网址为&#xf…

一 、环境的安装 Anaconda + Pycharm + PaddlePaddle

《从零到一实践&#xff1a;系统性学习生成式 AI(NLP)》 一 、环境的安装 Anaconda Pycharm PaddlePaddle 1. Anaconda 软件安装 Anaconda 软件安装有大量的教程&#xff0c;此处不在说明&#xff0c;安装完成之后界面如下&#xff1a; 2. 创建 Anaconda 虚拟环境 Paddl…

软考教材重点内容 信息安全工程师 第23章 云计算安全需求分析与安全保护工程

23.1.云计算基本概念 云计算就是在这样的需求驱动下而产生的一种计算模式。云计算通过虚拟化及网络通信技术&#xff0c;提供一种按需服务、弹性化的 IT 资源池服务平台。云计算的主要特征如下。 1. IT 资源以服务的形式提供 IT 资源以一种服务产品的形式提供&#xff0c;满…

蓝桥杯 19. 最大比例

最大比例 原题目链接 题目描述 X 星球的某个大奖赛设了 M 级奖励。每个级别的奖金是一个正整数。 并且&#xff0c;相邻两个级别间的比例是一个固定值&#xff0c;也就是说&#xff1a;所有级别的奖金构成一个等比数列。 例如&#xff1a; 奖金数列为 16, 24, 36, 54&…

基于 Python 的自然语言处理系列(82):Transformer Reinforcement Learning

&#x1f517; 本文所用工具&#xff1a;trl、transformers、peft、bitsandbytes &#x1f4d8; 官方文档参考&#xff1a;https://huggingface.co/docs/trl 一、引言&#xff1a;从有监督微调到 RLHF 全流程 随着语言大模型的发展&#xff0c;如何在大规模预训练模型基础上更精…

JAVA猜数小游戏

import java.util.Random; import java.util.Scanner;public class HelloWorld {public static void main(String[] args) {Random rnew Random();int luck_number r.nextInt(100)1;while (true){System.out.println("输入猜数字");Scanner sc new Scanner(System…

GPU渲染阶段介绍+Shader基础结构实现

GPU是什么 &#xff08;CPU&#xff09;Center Processing Unit:逻辑编程 &#xff08;GPU&#xff09;Graphics Processing Unit&#xff1a;图形处理&#xff08;矩阵运算&#xff0c;数据公式运算&#xff0c;光栅化&#xff09; 渲染管线 渲染管线也称为渲染流水线&#x…

Spring Boot + MyBatis 动态字段更新方法

在Spring Boot和MyBatis中&#xff0c;实现动态更新不固定字段的步骤如下&#xff1a; 方法一&#xff1a;使用MyBatis动态SQL&#xff08;适合字段允许为null的场景&#xff09; 定义实体类 包含所有可能被更新的字段。 Mapper接口 定义更新方法&#xff0c;参数为实体对象&…

单例模式:确保唯一实例的设计模式

单例模式&#xff1a;确保唯一实例的设计模式 一、模式核心&#xff1a;保证类仅有一个实例并提供全局访问点 在软件开发中&#xff0c;有些类需要确保只有一个实例&#xff08;如系统配置类、日志管理器&#xff09;&#xff0c;避免因多个实例导致状态混乱或资源浪费。 单…

UnoCSS原子CSS引擎-前端福音

UnoCSS是一款原子化的即时按需 CSS 引擎&#xff0c;其中没有核心实用程序&#xff0c;所有功能都是通过预设提供的。默认情况下UnoCSS应用通过预设来实现相关功能。 UnoCSS中文文档&#xff1a; https://www.unocss.com.cn 前有很多种原子化的框架&#xff0c;例如 Tailwind…

【Qwen2.5-VL 踩坑记录】本地 + 海外账号和国内账号的 API 调用区别(阿里云百炼平台)

API 调用 阿里云百炼平台的海内外 API 的区别&#xff1a; 海外版&#xff1a;需要进行 API 基础 URL 设置国内版&#xff1a;无需设置。 本人的服务器在香港&#xff0c;采用海外版的 API 时&#xff0c;需要进行如下API端点配置 / API基础URL设置 / API客户端配置&#xf…

C语言笔记(鹏哥)上课板书+课件汇总(结构体)-----数据结构常用

结构体 目录&#xff1a; 1、结构体类型声明 2、结构体变量的创建和初始化 3、结构体成员访问操作符 4、结构体内存对齐*****&#xff08;重要指数五颗星&#xff09; 5、结构体传参 6、结构体实现位段 一、结构体类型声明 其实在指针中我们已经讲解了一些结构体内容了&…