字节跳动2020秋招笔试题
文章目录
1、模型文件去重
- 【题目描述】
抖音上不同的用户类型我们有不同的用户模型文件。
我们有一个模型配置文件,里面有很多的不同的用户类型和他们对应的模型文件。我们需要找出每个模型对应的是哪些用户类型。
给定一行输入,格式是a b
a表示这个用户的用户类型,b表示这个用户对应的模型文件。
请你输出每个模型文件对应的用户类型。
注意1:每个模型文件可能对应多个用户类型,用户类型之间用空格作为切分。
注意2: 如果有多个用户类型输出,用户类型之间的排序按照字母表排序。
注意3: 如果有多个模型输出,模型输出的顺序按照模型文件在输入数据中顺序,即从上到下。
-
【输入描述】
输入第1行: 用户类型 N(表示有多少个 用户类型)
接下来的N行:用户类型 模型文件 -
【输出描述】
模型文件用户类型1 用户类型2 -
【示例1】
//输入
1
abc 1.txt
//输出
1.txt abc
- 【示例2】
//输入
5
abc 1.txt
aaa 2.txt
ccc 2.txt
bbb 2.txt
ddd 1.txt
//输出
1.txt abc ddd
2.txt aaa bbb ccc
- 【解题思路】
用一个map做hash,其中以string作为key,字符串去重集合set<string>
作为value。
- 【参考代码1】
#include<iostream>
#include<vector>
#include<set>
#include<unordered_map>
using namespace std;
int main()
{
int n;
string a, b;
vector<string> vct;
unordered_map<string, set<string>> unod_map;
cin >> n;
while (n--)
{
cin >> a >> b;
if (!unod_map.count(b))
{
vct.push_back(b);
}
unod_map[b].insert(a);
}
for (auto b:vct)
{
cout << b;
for (auto a:unod_map[b])
{
cout << " " << a;
}
cout << endl;
}
return 0;
}
/****
5
abc 1.txt
aaa 2.txt
ccc 2.txt
bbb 2.txt
ddd 1.txt
***/
2、穿越沙漠的补给次数
- 【题目描述】旅行者穿越沙漠的过程中需要不断地消耗携带的饮用水,到达终点前会经过几个绿洲,每个绿洲均设有水分补给站可以为旅行者提供水分补给并收取一定的费用。
沿途共有n个补给站,每个补给站收取的费用都一样,但是提供的水量不尽相同。起点到终点的距离为D公里,postion[i]表示第i个补给站距离起点的距离,单位为公里,supply[i]表示第i 个补给站可以提供的水量,单位为升。
假设旅行者在起点时携带了W升的水,每行走1公里需要消耗1升的水量,身上可携带的水量没有上限,且携带的水量多少不会对体能消耗产生影响,鉴于每次进补给站花费的钱都是一样多,期望用最少的补给次数到达终点,请帮忙计算最少的补给次数。
- 【输入描述】
第一行输入整数D和W, D表示起点到终点的距离,W表示初始携带的水量
第二行输入数组postion,长度为N,分别表示N个补给站分别距离起点的距离
第三行输入数组supply,长度为N, 分别表示N个补给站分别可以供给的水量
数据范围:1 <= D, W<=10^8, 0<=N<=1000, 0<position[i],supply[i]<D
- 【输出描述】
输出一个整数表示最少的补给次数,若无法到达终点则返回-1
- 【示例1】
//输入
10 4
1 4 7
6 3 5
//输出
1
- 【说明】
每行输入用空格隔开。起点到终点共10公里,初始时携带4升水,途径3个补给站。共需补给一次:只需在第1个补给站补给一次获得6升水,即可走完全程
- 【解题思路】
贪心。假设你现在有携带的水量为W,当前位置为curPos,那么你携带的水能够支撑你走到curPos+W位置,走到该位置之后你再考虑去该位置(如果有)及之前的水站加水(可能在该位置之前有多个水站),此外,为了保证最少的加水次数,应该到能加到最多水的水站加水,而且加完水之后应该给这个水站加一个标记(used数组),以后不能再到该水站取水。
- 【参考代码】
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
//#include<set>
//#include<unordered_map>
//#include <algorithm>
using namespace std;
void test(vector<int> &position, vector<int>& supply, vector<bool>& flag)
{
for (int i = 0; i < position.size(); i++)
{
cout << position[i] << " ";
}
cout << endl;
for (int i = 0; i < supply.size(); i++)
{
cout << supply[i] << " ";
}
cout << endl;
for (int i = 0; i < flag.size(); i++)
{
cout << flag[i] << " ";
}
cout << endl;
}
int solve(int D,int W,vector<int>& position, vector<int>& supply, vector<bool>& flag)
{
int cnt = 0;
int currpos = 0;
while (currpos<D)
{
currpos += W;
W = 0;
if (currpos>=D)
{
return cnt;
}
int index = -1;
for (int i = 0; i < position.size(); i++)
{
if (position[i]>currpos || flag[i])
{
continue;
}
if (supply[i]>W)
{
W = supply[i];
index=i;
}
}
if (index==-1)
{
return -1;
}
cnt++;
flag[index] = true;
}
return cnt;
}
int main()
{
int D, W;
int data;
vector<int> position;
vector<int> supply;
vector<bool> flag;
string line;
cin >> D >> W;
getline(cin, line);
getline(cin, line);
stringstream ss;
ss << line;
while (ss>>data)
{
position.push_back(data);
}
getline(cin, line);
ss.clear();
ss << line;
while (ss>>data)
{
supply.push_back(data);
}
for (int i = 0; i < position.size(); i++)
{
flag.push_back(false);
}
//test(position, supply, flag);
int cnt = solve(D,W,position, supply, flag);
cout << cnt << endl;
return 0;
}
/****
10 4
1 4 7
6 3 5
***/
4、简单变换
-
【题目描述】春节在家的凯凯真的是太无聊了,他准备和他家的猫玩一个游戏。
凯凯在黑板上写下了两个长度相等的数列a[1…n], b[1…n]。
现在他想让他的猫判断数列a能否通过一个操作变换成数列b。
这个操作是:在数列a中选择一个区间l-r,对这个区间所有的数字加上一个k。
其中1<=l<=r<=n, k>=0。
你可以帮帮可怜的小猫做出这个判断么? -
【输入描述】
首先输入一个数字t,表示有t组数据
每组数据的第一行为一个数字n 表示数列的长度
接下来两行每行有n个数字,分别为数组a和数组b -
【输出描述】
对于每组数据输出YES 或者 NO
表示数列a能否通过对应的操作变换成数列b。 -
【备注】
t<=10
n<=100000 -
【示例1】
//输入
2
6
3 7 1 4 1 2
3 7 3 6 3 2
5
1 1 1 1 1
1 2 1 3 1
//输出
YES
NO
说明
对于第一个样例可以对区间[1,4,1] 的每个数字加上2,即可把数列a转换成数列b
对于第二个样例没法做相应的操作
- 【解题思路】
维护出一个差分数组,然后对差分数组进行情况讨论即可。
- 【参考代码】
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
//#include<set>
//#include<unordered_map>
#include <algorithm>
using namespace std;
string solve(vector<int> &a)
{
int l = -1, r = -1, k = 0;
for (int i = 0; i < a.size(); i++)
{
if (a[i]<0)
{
return "NO";
}
if (a[i]>0)
{
if (l==-1)
{
l = i;
}
if (r==-1||r==i-1)
{
r = i;
}
else
{
return "NO";
}
if (k!=0&&k!=a[i])
{
return "NO";
}
k = a[i];
}
}
return "YES";
}
int main()
{
int t, n;
vector<int> a;
//vector<int> b;
int data;
cin >> t;
while (t--)
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> data;
a.push_back(data);
}
for (int i = 0; i < n; i++)
{
cin >> data;
a[i] = data - a[i];
}
string s = solve(a);
cout << s << endl;
}
return 0;
}
/****
2
6
3 7 1 4 1 2
3 7 3 6 3 2
5
1 1 1 1 1
1 2 1 3 1
***/
5、优惠券
- 【题目描述】
你有n种无门槛优惠券,每种优惠券有一个面值ai。当一件商品的售价≥ai时,你可以出示这种优惠券直接抵扣。抵扣后,优惠券不会被回收,可以继续使用。现在,你想要买m件商品,每件商品的售价是bi,请问你最少需要花费多少钱?
【输入描述】
第一行两个正整数n,m(1≤n,m≤106)
第二行n个正整数ai (0≤ai≤106),代表n种无门槛优惠券的面值 (不保证排序)
第三行m个正整数bi (0≤bi ≤106),代表m件商品的价格 (不保证排序)
【输出描述】
输出合理使用优惠券后,购买上述m件商品最少需要的花费。
【示例1】
输入
3 4
50 100 200
99 199 200 300
输出
248
【解题思路】
二分查找出当前最优的优惠券进行使用。
C++ lower_bound 与 upper_bound 函数
【参考代码】
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
//#include<set>
//#include<unordered_map>
#include <algorithm>
using namespace std;
int main()
{
int n, m;
vector<int> a;
vector<int> b;
int data;
int ans=0;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> data;
a.push_back(data);
}
sort(a.begin(), a.end());
for (int i = 0; i < m; i++)
{
cin >> data;
ans += data - *--upper_bound(a.begin(), a.end(), data);
}
cout << ans << endl;
return 0;
}
/****
3 4
50 100 200
99 199 200 300
***/
上一篇: 部署nginx遇到的问题_重定向次数过多或者干脆找不到路径
下一篇: 日常问题总结