2020.09.05 搜狗研发岗笔试 A~C题解
A. 三种商品,两个可以换一个任意的,三种各一个可以换一个奖品,问最多换几个奖品。
直接二分答案。
class Solution {
public:
int numberofprize(int a, int b, int c) {
int lo = 0, hi = 1E9;
int ret = 0;
auto check = [&](int val) {
int tmp = 0;
int x = a, y = b, z = c;
x -= val, y -= val, z -= val;
if (x >= 0) tmp += x, x = 0;
if (y >= 0) tmp += y, y = 0;
if (z >= 0) tmp += z, z = 0;
return tmp / 2 >= -(x + y + z);
};
while (lo <= hi) {
int mid = (lo + hi) >> 1;
if (check(mid)) {
ret = mid;
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return ret;
}
};
B. 盖房子什么的。
直接模拟。
class Solution {
public:
int getHouses(int t, int* xa, int xaLen) {
int ret = 2;
vector<int> x, a;
for (int i = 0; i < xaLen; i += 2) {
x.emplace_back(xa[i]);
a.emplace_back(xa[i + 1]);
}
int n = x.size();
if (n == 1) return 2;
for (int i = 0; i < n - 1; i++) {
double lo = (double)x[i] + (double)a[i] / 2.0;
double hi = (double)x[i + 1] - (double)a[i + 1] / 2.0;
if (hi - lo < t) continue;
if (hi - lo == t) {
ret++;
} else {
ret += 2;
}
}
return ret;
}
}; C. 构造密码什么的。
记搜,f(i,len)维护当前数字为i,目前匹配到长度为len时的方案数。用一个标记去判重。
using LL = long long;
class Solution {
public:
long long getPasswordCount(string password) {
int n = password.length();
LL f[11][55];
memset(f, -1, sizeof f);
function<LL(int, int, int flag)> dfs = [&](int i, int len, int flag) {
if (~f[i][len]) return f[i][len];
if (len == n) return 1LL - flag;
LL ret = 0;
double tmp = password[len] - '0' + i;
tmp = (double)(tmp) / 2.0;
if (tmp != (int)tmp) {
tmp++;
ret += dfs((int)tmp, len + 1, flag && ((int)tmp == password[len] - '0'));
}
tmp = (password[len] - '0' + i) / 2.0;
ret += dfs((int)tmp, len + 1, flag && ((int)tmp == password[len] - '0'));
return f[i][len] = ret;
};
LL ret = 0;
if (n == 1) return 9;
for (int i = 0; i <= 9; i++) {
memset(f, -1, sizeof f);
ret += dfs(i, 1, i == password[0] - '0');
}
return ret;
}
}; 

查看6道真题和解析