大厂笔试真题讲解—美团23年—小美的字符串变换

本题主要讲解小美的字符串变换的要点和细节,根据步骤一步步思考方便理解

提供c++的核心代码以及acm模式代码,末尾

题目描述

小美拿到了一个长度为 n 的字符串,她希望将字符串从左到右平铺成一个矩阵(先平铺第一行,然后是第二行,以此类推,矩阵有 x 行 y 列,必须保证 x * y=n,即每 y 个字符换行,共 x 行)。 

该矩阵的权值定义为这个矩阵的连通块数量。小美希望最终矩阵的权值尽可能小,你能帮小美求出这个最小权值吗? 

注:我们定义,上下左右四个方向相邻的相同字符是连通的。

输入描述

第一行输入一个正整数 n(1 <= n <= 10^4),代表字符串的长度。 

第二行输入一个长度为 n 的、仅由小写字母组成的字符串。

输出描述

输出一个整数表示最小权值。

输入示例
9
aababbabb
输出示例
2
提示信息

平铺为 3 * 3 的矩阵:

aab

abb

abb 

共有 2 个连通块,4 个 a 和 5 个 b。

具体要点(针对笔试的ACM模式进行讲解): 

1. 首先明确我们获取的输入是什么,分别是:

        正整数 n(1 <= n <= 10^4),代表字符串的长度。 

        长度为 n 的、仅由小写字母组成的字符串

    其次考虑输出是什么:即最小连通块的数量

所以我们先写好我们的输入和输出:

int main() {//获取输入int n;//正整数ncin >> n;string s;//字符串scin >> s;//执行函数,得到输出Solution sol;cout << sol.fun(n, s) << endl; //返回最小连通块的数量return 0;
}

2. 然后题目要求把s平铺成一个矩阵,没有给定矩阵的长宽,但是给了矩阵的长×宽=n

所以我们就要考虑到枚举所有形状的矩阵,对其每种形状进行计算和处理

下面我们用N代表长,M代表宽N

如何遍历所有的形状呢:我们首先会想到遍历N(1-n),去用n/N获取M的对应值,但是我们需要保证N是n的因数,即除完后没有余数。

所以我们接下里这样子写:

    int fun(int n, string s) {//接受我们的输入int N = 0, M = 0;//N代表行,M代表列int ans = INT_MAX;for (N = 1;N <= n;N++) {//遍历N,枚举所有的形状if (n % N == 0) {//保证没有余数M = n / N; //计算对应的Mans = min(ans, solve(N, M, s));//暂时不用管,还没讲到}}return ans;//我们的输出,最小的连通块数}

3. 接下来我们去写solve函数中的内容,老样子,首先明确solve的输入输出

        输入是N,M,s,输出是该形状下的连通块数量

然后考虑我们的函数内部要做些什么:

  • 我们虽然知道了N,M,但是具体矩阵内部元素我们还没有填充,需要用s去挨个填满,后续才能计算连通块
  • 计算连通块,我们要去判断一个位置的上下左右,是不是相同字符(然后继续判断该位置下个位置)不断递归,我们就会考虑用搜索算法(这里使用dfs深度优先)
  • 接着,虽然我们判断出来这个位置是不是连通,但是我们没有记录,我们需要维护一个一样形状的矩阵记录我们的判断结果,checklist
  • 等我们搜索完成一次后(检索了起始位置的字符相同的连通区域),就把连通区 blocknum++
  • 最后返回blocknum
    int solve(int N, int M, string s) {int blocknum = 0;vector<string>arr(N, string(M, ' '));//定义检查表vector<vector<int>> checklist(N, vector<int>(M, 0));//填充arrfor (int i = 0;i < N;i++) {for (int j = 0;j < M;j++) {arr[i][j] = s[i * M + j];}}//遍历每一个位置,每个位置都进行深度搜索,//虽然在dfs递归过程中,有的位置在dfs中被检索到了,//但是由于还有其他的不同字符的连通块,我们要对每个位置作为起始都搜索一遍for (int i = 0;i < N;i++) {for (int j = 0;j < M;j++) {if (checklist[i][j] == 0) {//执行深度优先搜索,递归dfs(arr, checklist, i, j, N, M);//等深度优先搜索完成之后,对block进行++blocknum++;}}}return blocknum;;}

4. 接着我们要把dfs写完整

首先考虑dfs的输入

        要对i,j的四周进行搜索,所以要保证不越界,需要N,M帮助判断

        要搜索,需要对象 arr

        要记录搜索结果,需要checklist

接着,考虑递归终止条件

        我们递归中维护checklist,所以只要操作checklist即可,不需要返回值

        当我们下个位置越界下个位置字符不等于当前字符checklist不等于0,我们就终止了递归

其中,我们要预先定义一个DIRECTIONS,用来计算上下左右的位置,

    void dfs(vector<string>& arr, vector<vector<int>>& checklist, int i, int j, int N, int M) {//搜索到该位置就置1,不需要return,直接对checklist操作checklist[i][j] = 1;//深度优先策略for (const auto& dir : DIRECTIONS) {//计算下一个位置的索引int i_next = i + dir.first;int j_next = j + dir.second;//对位置进行判断,是否在范围内,checklist是否==0,arr的值是否与上一个一致if (i_next >= 0 && i_next < N && j_next >= 0 && j_next < M && checklist[i_next][j_next] == 0 && arr[i][j] == arr[i_next][j_next])dfs(arr, checklist, i_next, j_next, N, M);}}
    //下,右,上,左const vector<pair<int, int>> DIRECTIONS = {{0, 1},{1, 0},{0, -1},{-1, 0}};

至此,我们就完成了这个代码的主要编写,对于这种比较复杂的代码,我们需要先一步步深入考虑

  • 先考虑输入输出,
  • 再考虑代码解决什么,
  • 解决主要问题之前我们需要构造什么,
  • 如果涉及递归,想清楚递归的终止条件,
  • 递归的参数可以再写递归过程中慢慢加入,
  • 考虑递归是否需要返回值(还是需要维护数组)

 希望我的讲解对你的学习有一点作用

完整代码如下:

#include <iostream>
#include <vector>
#include <cmath>
#include <climits> // Include this header for INT_MAXusing namespace std;
class Solution {//下,右,上,左const vector<pair<int, int>> DIRECTIONS = {{0, 1},{1, 0},{0, -1},{-1, 0}};
public:int solve(int N, int M, string s) {int blocknum = 0;vector<string>arr(N, string(M, ' '));//定义检查表vector<vector<int>> checklist(N, vector<int>(M, 0));//填充arrfor (int i = 0;i < N;i++) {for (int j = 0;j < M;j++) {arr[i][j] = s[i * M + j];}}for (int i = 0;i < N;i++) {for (int j = 0;j < M;j++) {if (checklist[i][j] == 0) {//执行深度优先搜索,递归dfs(arr, checklist, i, j, N, M);//等深度优先搜索完成之后,对block进行++blocknum++;}}}return blocknum;;}//深度优先搜索void dfs(vector<string>& arr, vector<vector<int>>& checklist, int i, int j, int N, int M) {//搜索到该位置就置1,不需要return,直接对checklist操作checklist[i][j] = 1;//深度优先策略for (const auto& dir : DIRECTIONS) {//计算下一个位置的索引int i_next = i + dir.first;int j_next = j + dir.second;//对位置进行判断,是否在范围内,checklist是否==0,arr的值是否与上一个一致if (i_next >= 0 && i_next < N && j_next >= 0 && j_next < M && checklist[i_next][j_next] == 0 && arr[i][j] == arr[i_next][j_next])dfs(arr, checklist, i_next, j_next, N, M);}}int fun(int n, string s) {int N = 0, M = 0;//N代表行,M代表列int ans = INT_MAX;for (N = 1;N <= n;N++) {//求出N和M的值if (n % N == 0) {M = n / N;ans = min(ans, solve(N, M, s));}}return ans;}
};int main() {int n;cin >> n;string s;cin >> s;Solution sol;cout << sol.fun(n, s) << endl;return 0;
}

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

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

相关文章

【使用python如何获取excel中sheet页的样式】

在Python中&#xff0c;要获取Excel文件中sheet页的样式&#xff08;如字体、颜色、边框等&#xff09;&#xff0c;你通常会使用openpyxl&#xff08;用于处理.xlsx文件&#xff09;或xlrd和xlwt&#xff08;用于处理较旧的.xls文件&#xff0c;但xlrd的新版本已不再支持.xlsx…

【C++提高编程-05】----C++之Deque容器实战

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

MySQL的三种重要的日志

日志 Mysql有三大日志系统 Undo Log&#xff08;回滚日志&#xff09;&#xff1a;记录修改前的数据&#xff0c;用于事务回滚和 MVCC&#xff08;多版本并发控制&#xff09;。 Redo Log&#xff08;重做日志&#xff09;&#xff1a;记录数据变更&#xff0c;用于崩溃恢复&…

【java】指定类,指定package,找到package下面,这个类的所有子类

目录 ■java代码 ■注意 ■运行效果 ■包的结构 ■java代码 package com.sxz.study.reflect;import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List;public class …

缓存技术实战[一文讲透!](Redis、Ecache等常用缓存原理介绍及实战)

目录 文章目录 目录缓存简介工作原理缓存分类1.按照技术层次分类2.按照应用场景分类3.按照缓存策略分类 应用场景1.硬件缓存2.软件缓存数据库缓存Web开发应用层缓存 3.分布式缓存4.微服务架构5.移动端应用6.大数据处理7.游戏开发 缓存优点缓存带来的问题 常见常用Java缓存技术1…

Unity 之通过自定义协议从浏览器启动本地应用程序

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 之通过自定义协议从浏览器启动本地应用程序 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进…

树莓派等Linux开发板上使用 SSD1306 OLED 屏幕,bullseye系统 ubuntu,debian

Raspberry Pi OS Bullseye 最近发布了,随之而来的是许多改进,但其中大部分都在引擎盖下。没有那么多视觉差异,最明显的可能是新的默认桌面背景,现在是大坝或湖泊上的日落。https://www.the-diy-life.com/add-an-oled-stats-display-to-raspberry-pi-os-bullseye/ 通过这次操…

Spring中获取bean的三种常用方式

在Spring框架中&#xff0c;一个bean是指由SpringIOC容器管理的一个Java对象。Spring提供了一种依赖注入的机制&#xff0c;可以通过在配置文件中配置bean的定义&#xff0c;实现在代码中通过IOC容器获取bean的实例。 方法一 根据名称获取Bean public class App {public sta…

ArrayList<Integer>()转为int[]的几种方式

目录 方法1&#xff1a;使用Arrays类中的copyOfRange方法 示例代码&#xff08;方法一&#xff09; 方法2&#xff1a;利用Java Streams 示例代码&#xff08;方法二&#xff09; 注意事项 方法1&#xff1a;使用Arrays类中的copyOfRange方法 Arrays.copyOfRange()可以用…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 特惠寿司(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 特惠寿司(100分) 🌍 评测功能需要订阅专栏后私信联系清隆解…

王思聪日本街头在被偶遇

王思聪日本街头再被偶遇&#xff0c;甜蜜约会日常成网友热议焦点近日&#xff0c;有网友在日本街头再次偶遇了“国民老公”王思聪&#xff0c;这次他不仅携带着一位美丽的女友&#xff0c;还展现出了两人之间亲密无间的互动&#xff0c;让不少网友感叹&#xff1a;这真的是每天…

如何使用 STARTTLS 加密 OpenLDAP 连接

简介 OpenLDAP提供了一个灵活且得到良好支持的LDAP目录服务。然而&#xff0c;默认情况下&#xff0c;服务器本身是通过未加密的网络连接进行通信的。在本指南中&#xff0c;我们将演示如何使用STARTTLS加密连接到OpenLDAP&#xff0c;以将传统连接升级为TLS。我们将使用Ubunt…

八、BGP

目录 一、为何需要BGP&#xff1f; 二、BGP 2.1、BGP邻居 2.2、BGP报文 2.3、BGP路由 2.4、BGP通告遵循原则 2.5、BGP实验 第一步&#xff1a;建立邻居 第二步&#xff1a;引入路由 BGP路由黑洞 路由黑洞解决方案 1、IBGP全互联 2、路由引入 3、MPLS 多协…

甘肃这款饼子很火 你是否有吃过呢

白吉饼那独特的外形&#xff0c;圆圆的十分可爱。&#x1f44f;它的表皮酥脆&#xff0c;内里绵软&#xff0c;麦香四溢。&#x1f60b;拿在手里沉甸甸的&#xff0c;就知道用料十足。 无论是直接吃&#xff0c;感受那纯粹的面香&#xff0c;还是夹上腊汁肉&#xff0c;变成美味…

web前端换行命令:深入解析与实用技巧

web前端换行命令&#xff1a;深入解析与实用技巧 在Web前端开发中&#xff0c;换行命令是一项基础而重要的技能。它涉及到文本排版、布局控制以及用户体验的多个方面。本文将通过四个方面、五个方面、六个方面和七个方面的详细阐述&#xff0c;带您深入了解Web前端换行命令的奥…

ThinkPHP5.0 apache服务器配置URL重写,index.php去除

本地环境wamp .htaccess文件代码 <IfModule mod_rewrite.c>Options FollowSymlinks -MultiviewsRewriteEngine onRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] </IfModule> 踩过这个坑&a…

关于编程思想

面向过程思想 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次调用就可以了 JS就是典型的面向过程的编程语言 优点&#xff1a; 性能比面向对象高&#xff0c;适合跟硬件联系很紧密的东西&…

000.双指针方法题解目录

000.双指针方法题解目录 167. 两数之和 II - 输入有序数组&#xff08;中等&#xff09;

dbForge Studioor MySQL v6 解锁版 安装教程(MYSQL数据库客户端)

前言 dbForge Studioor MySQL是一个在Windows平台被广泛使用的MySQL客户端&#xff0c;它能够使MySQL开发人员和管理人员在一个方便的环境中与他人一起完成创建和执行查询&#xff0c;开发和调试MySQL程序&#xff0c;自动化管理MySQL数据库对象等工作。 一、下载地址 下载链…

什么是GPT-4

什么是GPT-4 ChatGPT 可以说&#xff0c;ChatGPT的发展&#xff0c;主要的分水岭在GPT-4&#xff0c;GPT-4主要是文本对话&#xff0c;且训练度也不够完善。GPT-4之后不但训练度得到了巨大提升&#xff0c;模型支持的参数量更是预计有1万亿参数&#xff0c;在这之后出现的GPT-4…