8.20 美团笔试
T1 构造交替字符
直接构造即可
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin >> n;
string a, b;
cin >> a >> b;
string ans;
for (int i = 0; i < n; ++i) {
ans += a[i];
ans += b[i];
}
cout << ans << endl;
return 0;
} T2 找到哨岗的位置
在 nxn 的方格中,给定三个坐标,以及哨岗到这三个点的曼哈顿距离,求哨岗的位置。如果有多个满足的点,选择字典序最小的坐标。
思路:
直接暴力,遍历所有满足要求的点,然后求交集。
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
pair<int, int> op(int x, int y, int dx, int dy, int t) {
switch(t) {
case 0: return make_pair(x+dx, y+dy);
case 1: return make_pair(x-dx, y+dy);
case 2: return make_pair(x+dx, y-dy);
case 3: return make_pair(x-dx, y-dy);
}
return make_pair(1, 1);
}
int main() {
int n; cin >> n;
vector<int> xx(3), yy(3), dd(3);
set<pair<int, int>> ans;
for (int i = 0; i < 3; ++i) {
cin >> xx[i] >> yy[i];
}
for (int i = 0; i < 3; ++i) cin >> dd[i];
for (int i = 0; i < 3; ++i) {
set<pair<int, int>> nloc;
set<pair<int, int>> validl;
int d = dd[i], x = xx[i], y = yy[i];
for (int dx = 0; dx <= d; ++dx) {
int dy = d - dx;
for (int t = 0; t < 4; ++t) {
pair<int, int> co = op(x, y, dx, dy, t);
int nx = co.first, ny = co.second;
if (nx > 0 && nx <= n && ny > 0 && ny <= n) {
validl.emplace(nx, ny);
}
}
}
if (ans.empty()) {
ans = move(validl);
} else {
set_intersection(all(ans), all(validl), inserter(nloc, nloc.begin()));
ans = move(nloc);
}
}
cout << ans.begin()->first << " " << ans.begin()->second << endl;
return 0;
} T3 最高效率的复习
小明要期末考试了,但是他并没有准备好,每门课都有一个分数和拿到分数的概率。小明可以选择复习 m 门课,这 m 门课的概率将会提升至 100%。
思路:
我们先求出期望分数,然后求出每门课可以提升的分数(总分 - 期望分数),然后根据提升分数排序,选择前 m 个分数即可。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int n, m;
cin >> n >> m;
vector<ll> p(n), a(n);
for (auto& e : p) cin >> e;
for (auto& e : a) cin >> e;
for (int i = 0; i < n; ++i) {
p[i] *= a[i];
}
for (int i = 0; i < n; ++i) {
a[i] = a[i] * 100 - p[i];
}
sort(a.begin(), a.end(), greater<ll>());
ll ans = 0;
for (int i = 0; i < n; ++i) {
ans += p[i];
}
for (int i = 0; i < min(n, m); ++i) {
ans += a[i];
}
double ret = (double) ans / 100.;
cout << fixed << setprecision(2) << ret << endl;
return 0;
} T4 变为相同串的最小代价
把两个数组变为完全相同数组的最小代价是多少?
可以进行两种操作:
- 选择一个数组中的元素 a,把它删去,代价为 abs(a)
- 选择一个数组中的元素 a,把它变为 b,代价为 abs(a-b)
思路:
可以用动态规划求解,假设我们用 表示数组 A[:i] 与 B[:j] 完全相等需要的代价,那么很容易写出转移方程:
$$
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define maxn 2005
ll f[maxn][maxn];
int main() {
int n, m;
cin >> n >> m;
vector<int> a(n), b(m);
for (auto& e : a) cin >> e;
for (auto& e : b) cin >> e;
memset(f, 0x3f, sizeof(f));
f[0][0] = 0;
for (int i = 1; i <= m; ++i) {
f[0][i] = f[0][i-1] + abs(b[i-1]);
}
for (int j = 1; j <= n; ++j) {
f[j][0] = f[j-1][0] + abs(a[j-1]);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
// del the a[i]
f[i+1][j+1] = min(f[i+1][j+1], f[i][j+1] + abs(a[i]));
// del the b[j]
f[i+1][j+1] = min(f[i+1][j+1], f[i+1][j] + abs(b[j]));
// del modify the a[i] to b[j]
f[i+1][j+1] = min(f[i+1][j+1], f[i][j] + abs(a[i] - b[j]));
}
}
cout << f[n][m] << endl;
return 0;
} T5 压住试卷的最小重量
每张试卷都需要至少 bi 的重量压住,我们有 m 中石头,每个石头的重量为 ai,那么总共需要多少重量的石头?
思路:
选择刚好可以压住试卷的最小石头
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> a(m), b(n);
for (auto& e : b) cin >> e;
for (auto& e : a) cin >> e;
sort(a.begin(), a.end());
int ans = 0;
for (auto e : b) {
auto it = lower_bound(a.begin(), a.end(), e);
if (it == a.end()) {
ans = -1; break;
}
ans += *it;
}
cout << ans << endl;
return 0;
} #美团笔试##校招##笔试##题解##机试#
腾讯公司福利 1155人发布