华为4.20od笔试
写在前面的话,哥们很菜,下面写的代码可能只能过样例,不过捏!哥们就是又菜又爱玩,诶,无所吊谓。
吐槽几句,现在这暑期实习难度逐年变大了,好多人都说,快比上正式招聘(秋招)的难度了,真的寄。
送互联网一套马师傅拳法,给我天天练,把身体练暖和了!
第一题-----------------二分法
某农场主管理了一大片果园,fields[i]表示不同果林的面积,单位:(m^2),现在要为所有的果林施肥目必须在n天之内完成,否则影响收成。小布是果林的工作人员,他每次选择一片果林进行施肥,且一片果林施肥完后当天不再进行施肥作业。假设施肥机的能效为k,单位:(m^2/day),请问至少租赁能效k为多少的施肥机才能确保不影响收成?如果无法完成施肥任务,则返回-1。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
using namespace std;
int getday(int x, const vector<int>& a) //获取天数
{
int count = 0;
for (auto j : a)
{
if (x >= j) count++;
else
{
if (j % x != 0)
{
count += j / x + 1;
}
else
{
count += j / x;
}
}
}
return count;
}
int main()
{
int n;
cin >> n;
int day;
int max = INT_MIN;
cin >> day;
vector<int> a;
while(n--) //输入果林面积
{
int num;
cin >> num;
a.push_back(num);
if (num > max) max = num;
}
if (a.size() > day) // 特殊情况
{
cout << -1;
return 0;
}
int left = 0;
int right = max;
int min = INT_MAX;
while (left <= right)
{
int mid = left + (right - left) / 2;
int target = getday(mid, a);
if (target == day) //说明刚刚好满足
{
if (min > target ) min = mid;//但可能还有更小的,所以先记录下
right = mid - 1;
}
else if (target < day) //这天数太小了,说明能效太大了
{
right = mid - 1;
}
else //天数过大,说明能效太小,需要将能效范围右移
{
left = mid + 1;
}
}
cout << min; //输出最小能效
return 0;
}
第二题------------前缀积
给你一个整数数组nums,请计算数组的中心位置。数组中心位置是数组的一个下标,其左侧所有元素相乘的积等于右侧所有无素相乘的积。
数组第一个元素的左侧积为1,最后一个元素的右侧积为1
如果数组有多个中心位置,应该返回最靠近左边的那一个。如果数组不存在中心位置,返回-1。
vector<int> nums;
vector<int> pres;
void solv() //判断是否为中心位置
{
for (int i = 0; i < nums.size(); i++)
{
if (pres[i] == pres[nums.size()] / pres[i + 1])
{
cout << i << endl;
return;
}
}
cout << -1 << endl;
}
int main()
{
int n;
while (cin >> n)
{
nums.push_back(n);
if (getchar() == '\n') break; //遇到回车符就跳出
}
pres.resize(nums.size() + 1);
pres[0] = 1;
for (int i = 1; i <= nums.size(); i++) //计算数组的前缀积
{
pres[i] = pres[i - 1] * nums[i - 1];
}
solv();
return 0;
}
第三题-----------模拟
大众对垃圾短信深恶痛绝,希望能对垃圾短信发送者进行识别,为此,很多软件增加了垃圾短信识别机制。经分析,发现正常用户的短信通常具备交互性,而垃圾短信往往都是大量单向的短信,按照如下规则进行垃圾短信识别:
本题中,发送者A符合以下条件之一的,则认为A是垃圾短信发送者:
*A发送短信的接收者中,没有发过短信给A的人数L> 5;
*A发送的短信数-A接收的短信数M>10
*如果存在X,A发送给X的短信数-A接收到X的短信数N>5;
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;
int N;
// 发送方和接收方的计数器
unordered_map<int, int> send_cnter;
unordered_map<int, int> revi_cnter;
// 每个人发送和接收的名单
unordered_map<int, unordered_set<int>> sender;
unordered_map<int, unordered_set<int>> revicer;
// 每个人发送和接收的名单,用vector存储
unordered_map<int, vector<int>> sender1;
unordered_map<int, vector<int>> revicer1;
// 给定的人的ID
int ID;
// 判断给定ID的人是否符合要求
void solv() {
bool flag = false; // 是否垃圾发送者的标记
int L = 0;
for (int send : sender[ID]) {
if (sender[send].count(ID) == 0) L += 1;
}
if (L > 5) flag = true;
int M = send_cnter[ID] - revi_cnter[ID];
if (M > 10) flag = true;
// 统计给定ID的人发送和接收信息的频率
unordered_map<int, int> cnter;
for (int x : sender1[ID]) cnter[x]++;
for (int x : revicer1[ID]) cnter[x]--;
for (auto [k, v] : cnter) { //c++17的特性,需要注意下
if (v > 5) {
flag = true;
break;
}
}
// 根据标记输出结果
if (flag) {
cout << "true " << L << " " << M << endl;
} else {
cout << "false " << L << " " << M << endl;
}
}
int main() {
cin >> N;
// 初始化
for (int i = 0; i <= 100; i++) {
send_cnter[i] = 0;
revi_cnter[i] = 0;
sender[i] = {};
revicer[i] = {};
sender1[i] = {};
revicer1[i] = {};
}
// 输入每个人发送和接收的信息
for (int i = 0; i < N; i++) {
int fr, to;
cin >> fr >> to;
sender[fr].insert(to);
revicer[to].insert(fr);
send_cnter[fr]++;
revi_cnter[to]++;
sender1[fr].push_back(to);
revicer1[to].push_back(fr);
}
// 输入给定的人的ID并求解
cin >> ID;
solv();
return 0;
}
od笔试的难度还是要比正式的华为笔试要小一点的,努力认真生活好累啊,
看到这里兄弟能不能别光收藏,点个赞,留个言鼓励下哥们啊,哥们好有力继续冲!
#华为信息集散地##暑期实习##华为笔试##笔试#