恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经,目前已更新至美团、微软…
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝
第一题:字符串压缩
题目描述
给定一段英文句子和一个英文单词列表。 英文句子包含英文单词和标点符号,其中:
- 英文单词只包含[a-zA-Z]范围内的字符;
- 标点符号包括逗号、句号、双引号(双引号两边至少有一个空格)。
如果列表中有单词在句子中存在(大小写不敏感)且该单词未被双引号包含,则使用该单词在列表中的索引值(索引值从0开始)代替句子中的该单词,如果英文单词列表中存在重复的英文单词,则以该单词最后一次出现的索引值进行替换。
输入描述
第一行:一段英文句子
第二行:英文单词列表
提示:
每个英文单词长度在[150]范围内。
输入的英文句子长度在[0,10000]范围内。
输入的英文单词列表长度在[0,100000]范围内。英文句子中不会出现双引号不匹配的情况。
Hello world.
Good Hello LOOP
解释:hello在英文句子中存在,则使用hello的索引值进行替换,得到结果为1w
orld.
输出描述
替换后的英文句子
1world.
代码
CPP版本
#include<bits/stdc++.h>
using namespace std;
map<string,int>aa;
void change(string &s){
for(int i=0;i<s.length();i++){
if(s[i]>='a' &&s[i]<='z'){
s[i]-=32;
}
}
}
bool check(char aa){
if(aa>='A' && aa<='Z')return true;
if(aa>='a' && aa<='z')return true;
return false;
}
int main(){
string s;
getline(cin,s);
string s1;
int tt=1;
while(cin>>s1){
// string s2;
change(s1);
// cout<<s1<<' '<<tt<<endl;
aa[s1]=tt;
tt++;
//if(tt>=8)break;//调试用的
}
string ans;
int begin1=0;
for(int i=0;i<s.length();i++){
if(s[i]=='"'){
i++;
while(i<s.length() &&s[i]!='"')i++;
// ans+='"';
}
while(i<s.length() &&check(s[i])){
i++;
}
if(i==s.length())break;
string tl=s.substr(begin1,i-begin1);
begin1=i+1;
string ts=tl;
change(tl);
// cout<<"start"<<tl<<' '<<aa[tl]<<endl;
if(aa[tl]!=0)ans+=to_string(aa[tl]-1);
else ans+=ts;
ans+=s[i];
}
cout<<ans<<endl;
return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
JS版本
//前后华为给的代码我忘了,直接写核心
//处理句子和字典
var sentence = inputArrays[0].split(" ")
var dictionary = inputArrays[1].split(" ")
//大小写不敏感,把字典全改大写,句子里面有特殊字符,改不了
dictionary = Array.from(dictionary,item=>item.toUpperCase())
//处理引号内的,思路是定义一个开关。当时引号单词忘了咋拼。。
var isInside = false
for(let i in sentence){
if(sentence[i]=='"'){
isInside = !isInside //开关
continue //引号不进行字典查询
}
var str = sentence[i].replace(/[^a-zA-Z]/,"")
//含有特殊字符的话toUpperCase()会报错,在这里卡了蛮久,属于是考场上学知识了
if(dictionary.includes(str.toUpperCase())){
//之前用for循环倒序查字典的,过80%,剩下的超时,所以优化,先查有没有
var j = sentence[i] = dictionary.lastIndexOf(str.toUpperCase())
//最后的索引,当然lastIndexOf()
str.length==sentence[i].length? sentence[i]=j:sentence[i]=j+sentence[i][sentence[i].length-1]
//通过对比长度来看有没有句号逗号,有的话取过来
}
}
console.log(sentence.join(" "))
// vx公众号关注TechGuide 实时题库 闪电速递
第二题:士兵的任务2
题目描述
士兵在迷宫中执行任务,迷宫中危机重重,他需要在在最短的时间内到达指定的位害。你可以告诉上兵他最少需要多长时间吗?
输入一个n*m的迷宫中,迷宫中0为路,1为墙,2为起点,3为终点,4为陷阱,6为炸弹。士兵只能向上下左右四个方向移动,如果路径上为墙,不能移动。已知每走一步需要花费1个单位的时间,走到陷阱上需要花费3个单位的时间,走到炸弹上将会激活炸弹将炸弹上下左右的墙炸为路。
注意点:
- 炸弹只能炸聚地,不会炸掉陷阱
- 炸弹、陷阱只能发挥一次作用
- 迷言为最大为25*25
- 用例保证十兵一定有方法能到达终点
输入
输出
样例1
复制 输入:44
1021
输入描述
第一行:n和m
第二行开始:n*m的矩阵
4 4
1 1 1 1
1 6 2 1
1 1 0 1
1 3 1 1
输出描述
最少需要的单位时间
3
解释:
士兵在位置2,向左移动到炸弹上,会将炸弹周围的墙炸掉,向下走两步
即可到达终点
思路
代码
CPP版本
#include <iostream>
#include <queue>
using namespace std;
struct node
{
int x, y, t;
node() {}
node(int a, int b, int c) : x(a), y(b), t(c) {}
bool operator<(const node &a) const
{
return t > a.t;
}
};
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int g[30][30], vis[30][30];
int n, m, ans = 0;
priority_queue<node> q;
int main()
{
cin >> n >> m;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin >> g[i][j];
if (g[i][j] == 2)
{
vis[i][j] = 1;
q.push(node(i, j, 0));
}
}
}
while (!q.empty())
{
node cur = q.top();
q.pop();
for (int i = 0; i < 4; ++i)
{
int tx = cur.x + dx[i];
int ty = cur.y + dy[i];
if (tx < 0 || ty < 0 || tx >= n || ty >= n || vis[tx][ty] || g[tx][ty] == 1)
continue;
if (g[tx][ty] == 3)
{
ans = cur.t + 1;
break;
}
vis[tx][ty] = 1;
if (g[tx][ty] == 4)
q.push(node(tx, ty, cur.t + 3));
else if (g[tx][ty] == 6)
{
q.push(node(tx, ty, cur.t + 1));
for (int j = 0; j < 4; ++j)
{
int xx = tx + dx[j];
int yy = ty + dy[j];
if (g[xx][yy] == 1)
g[xx][yy] = 0;
}
}
else
q.push(node(tx, ty, cur.t + 1));
}
if (ans)
break;
}
cout << ans;
return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
第三题:高速公路休息站充电规划 (部分AC)
题目描述
张三购买了一辆续航里程数达1000公里的某自动驾驶新能源车。 某一天车辆充满电后,需从甲城出发前往距离D公里远的乙城,全程走高速。
车载导航提示沿途有N个休息站均可提供充电服务,各休息站均可实时提供当前充电排队时间(小时)。
请协助规划时间最优的休息站充电方案,返回最短的旅行用时。
为方便计算,高速上的行驶速度固定为100公里/小时。 规划时可不必考虑保留安全续航里程数,汽车可以将电完全用光,1000公里续航的汽车按100公里/小时,可以开10个小时。每次充电时间固定为1小时,完成后电量充满。各站点充电排队时间不会变化,充电排队过程不耗电。
输入描述
第一行表示甲乙两城的距离D,单位为公里;
第二行表示沿途的休息站数量N;
第三行起,每行2个数据,分别表示休息站距离甲城的距离,以及充电排队所需时间(小时),(各休息站按离从近到远排序)
0<=D<=1000000,D是100的整数倍
0<=N<=10000
1500
4
300 2
600 1
1000 0
1200 0
输出描述
旅程总计花费的最短时间(小时)
若无法到达终点,则返回-1
16
解释:
最佳方案:只在第3个休息站(位置1000)进行充电
1500公里的行程耗时:15小时
充电排队0小时,充电1小时
最快旅程总计花费16小时
其他方案:在第2个休息站(位置600)进行充电,总计花费17小时
其他方案:在第2个休息站(位置600)和第4个休息站(位置1200)进行充电,总计花费19小时
思路
利用动态规划+加回退搜索
把起始点设为0,每次到达一个新的站点,便进行回退搜索,一直搜索到1000公里以内且距离最远的充电站点k,然后从k站点开始遍历,一直遍历到当前站点,找到最短到达当前站点的时间,然后保存到当前站点的时间数组ans中,不断循环遍历,最终遍历到终点。
代码
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
int n, m;
//参数输入
cin >> n;
cin >> m;
//初始化站点数组,将起点和终点也纳入数组中
vector<vector<int>> f(m+2, vector<int>(2));
//起点的距离和等待时间都设为0
f[0][0] = 0;
f[0][1] = 0;
//终点的距离设为n,等待时间设为0
f[m+1][0] = n;
f[m+1][1] = 0;
//开始加入各个站点
for (int i = 1; i < m+1; i++) {
cin >> f[i][0];
cin >> f[i][1];
cout << f[i][0] << ' ';
cout << f[i][1] << ' ';
}
//初始化到达站点的时间,将起点和终点也纳入数组中
vector<int> ans(m + 2);
ans[0] = 0;
//开始计算各个站点
for (int i = 1; i < m + 2; i++) {
//将所有距离在1000以内的站点找出来
int k = i - 1;
while (k > 0 && (f[i][0] - f[k][0] < 1000)){
k--;
}
//这里除了起始站点以外,多超了一个站点,因此k需要加一
if (k != 0) {
k++;
}
//对每个可以直接到达的站点进行遍历,找出最小的时间站点
int min_time = INT_MAX;
for (; k < i; k++) {
int cur_time = (f[i][0] - f[k][0]) / 100 + ans[k] + f[i][1];
if (k != 0) {
cur_time++;
}
min_time = min(min_time, cur_time);
}
}
getchar();
cout << ans[m+1] << endl;
getchar();
}
// vx公众号关注TechGuide 实时题库 闪电速递