只有三题,比美团都简单,就是单选题和多选题很恶心
第一题
给你两个数组 a, b,长度均为 n(n≤105),你可以从 a 中删除一个元素或从 b 中删除一个元素,求删除后的 sum(a) ^ sum(b) 的最大值
那直接枚举删掉哪一个就可以了
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "/Users/aaron/Documents/template/debug.hpp"
#else
#define debug(...) 42
#endif
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<int> b(n);
for (int i = 0; i < n; i++) {
cin >> b[i];
}
long long sa = accumulate(a.begin(), a.end(), 0LL);
long long sb = accumulate(b.begin(), b.end(), 0LL);
long long mx = 0;
for (auto x : a) {
long long s = sa - x;
mx = max(mx, s ^ sb);
}
for (auto x : b) {
long long s = sb - x;
mx = max(mx, s ^ sa);
}
cout << mx << '\n';
return 0;
}
第二题
打怪,怪物血量为 H,你有两种牌,牌1和牌2,输入为 t,x,t 为牌的类型,牌必须按顺序打出去,牌1和牌2的效果分别为:
1 x: 获得 x 个骰子
2 x: 对怪物直接造成 x 点伤害,并抛出你现在有的所有骰子,造成骰子点数之和的伤害
问:秒杀怪物的概率是多少?
- Observation 1: 只有牌2能造成伤害
- Observation 2: 造成 x 点伤害之后,怪物的血量为 h−x, 手中有 cnt 个骰子,秒杀怪物的概率不好算,可以算它的对立事件,cnt 个骰子掷出的点数全部小于 ⌈h−xcnt⌉
1−(p−16)cnt
其中
p=⌈h−xcnt⌉
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "/Users/aaron/Documents/template/debug.hpp"
#else
#define debug(...) 42
#endif
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout << fixed;
cout.precision(10);
int n, h;
cin >> n >> h;
int cnt = 0;
auto power = [&](double x, double y, int p) {
double res = 1.;
for (int i = 0; i < p; i++) {
res *= 1. * x / y;
}
return res;
};
for (int i = 0; i < n; i++) {
int t, x;
cin >> t >> x;
if (t == 2 && x >= h) {
cout << 1. << '\n';
return 0;
}
if (t == 1) {
cnt += x;
} else {
int hp = (h - x);
if (hp <= cnt) {
cout << 1. << '\n';
return 0;
}
double bad = power(((hp + cnt - 1) / cnt) - 1, 6, cnt);
if (1 - bad >= 0) {
cout << 1 - bad << '\n';
return 0;
}
}
}
cout << 0. << '\n';
return 0;
}
第三题
给你一个数组 a,ai≤109,表示 b 中有 ai 个 i,例如 a=[2,1,2], 则 b=[1,1,2,3,3],问 b 中所有子数组的极差之和是多少,答案对 109+7 取模。极差是指数组中最大值减掉最小值。
ai≤109,直接构造 b 肯定不行,但是容易发现答案是:
n−1∑i=0(ai×n−1∑j=i+1(j−i)×aj)
考虑怎么优化后面那部分的计算,展开可以发现:
a0×(a1+2×a2+3×a3+4×a4+5×a5)
a1×(a2+2×a3+3×a4+4×a5)
a2×(a3+2×a4+3×a5)
可以发现第 i 项比第 i−1 项少一个
j=n−1∑j=iaj
考虑 dp 计算结果:
dp[i]=dp[i−1]−j=n−1∑j=iaj
后面部分预处理出来即可,复杂度 O(n)
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "/Users/aaron/Documents/template/debug.hpp"
#else
#define debug(...) 42
#endif
template <typename T>
T inverse(T a, T m) {
T u = 0, v = 1;
while (a != 0) {
T t = m / a;
m -= t * a; swap(a, m);
u -= t * v; swap(u, v);
}
assert(m == 1);
return u;
}
template <typename T>
class Modular {
...
constexpr int md = (int) 1e9 + 7;
using Mint = Modular<std::integral_constant<decay<decltype(md)>::type, md>>;
// vector<Mint> fact(1, 1);
// vector<Mint> inv_fact(1, 1);
//
// Mint C(int n, int k) {
// if (k < 0 || k > n) {
// return 0;
// }
// while ((int) fact.size() < n + 1) {
// fact.push_back(fact.back() * (int) fact.size());
// inv_fact.push_back(1 / fact.back());
// }
// return fact[n] * inv_fact[k] * inv_fact[n - k];
// }
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<long long> f(n + 1);
for (int i = 0; i < n; i++) {
f[i + 1] = f[i] + a[i];
}
vector<Mint> dp(n);
for (int i = 0; i < n; i++) {
dp[0] += 1LL * i * a[i];
}
for (int i = 1; i < n; i++) {
dp[i] = dp[i - 1] - (f.back() - f[i]);
}
Mint ans = 0;
for (int i = 0; i < n; i++) {
ans += a[i] * dp[i];
}
cout << ans << '\n';
return 0;
}