目录
[换水问题 II](#换水问题 II)
哈沙德数
原题链接
思路分析
签到题,不说了
AC代码
cpp
class Solution:
def sumOfTheDigitsOfHarshadNumber(self, x: int) -> int:
k = sum(int(x) for x in str(x))
return k if x % k == 0 else -1
换水问题 II
原题链接
思路分析
赛场为了速度直接模拟,应该可以推公式的,也不说了
AC代码
cpp
class Solution {
public:
int maxBottlesDrunk(int a, int b) {
int ret = a, cur = a;
while(cur >= b){
ret ++, cur = cur - b + 1, b++;
}
return ret;
}
};
交替子数组计数
原题链接
思路分析
对于一个长度为n的交替数组,可以拆分成n个长度为1的交替子数组,n-1个长度为2的交替子数组...一个长度为n的交替子数组
那么对于一个连续的交替子数组而言其贡献就i是(n + 1) * n / 2
那么我们可以一次遍历中找到所有的连续的交替子数组累加其贡献即可
时间复杂度:O(n)
AC代码
cpp
class Solution {
public:
long long countAlternatingSubarrays(vector<int>& nums) {
int pre = -1;
long long ret = 0, cur = 0;
for(auto x : nums){
if(x != pre){
cur ++;
}
else{
ret += (cur + 1) * cur / 2;
cur = 1;
}
pre = x;
}
ret += (cur + 1) * cur / 2;
return ret;
}
};
最小化曼哈顿距离
原题链接
思路分析
对于坐标(a, b),(c, d)
其曼哈顿距离为|a - c| + |b - d|,我们不妨设a > c, b > c
那么曼哈顿距离:a + b - (b + d) = a + b - b - d
我们发现第二个坐标各个维度的系数一定跟第一个坐标各个维度的系数相反
则我们不妨设第一个坐标的系数为(t1, t2),第二个为(-t1, -t2)
对任意两个n维度坐标(a1......an), (b1......bn)求曼哈顿距离:
有
我们发现我们只需要枚举向量(t1......tn)即可,即2^n种取值,每种向量下每个坐标都可以变换出一个值,该向量下的最大曼哈顿距离就是最大值减去最小值
对于本题而言,向量维度为2,则我们只需要枚举4次,每次遍历一遍点对
这样求出了最大值,而题目要的是删除一个坐标后最大值的最小值,显然要删除的就是最大值对应的两个坐标中的一个
我们维护最大值的时候记录此时用到的两个点对,然后枚举删除任意一个后的最大值,取最小的那个即可
时间复杂度O(n)
AC代码
cpp
class Solution {
public:
int minimumDistance(vector<vector<int>>& points) {
int n = points.size(), ret = 1e9, s = 0;
unordered_set<int> id;
for(int i = 0, ed = (1 << 2); i < ed; i++){
int ma = -1e9, mi = 1e9, mai, mii;
for(int j = 0, s; j < n; j++){
int sum = 0;
for(int k = 0; k < 2; k++)
if(i >> k & 1) sum -= points[j][k];
else sum += points[j][k];
if(sum > ma) ma = sum, mai = j;
if(sum < mi) mi = sum, mii = j;
}
if(ma - mi > s) s = ma - mi, id.clear(), id.insert(mai), id.insert(mii);
else if(ma - mi == s) id.insert(mai), id.insert(mii);
}
for(auto x : id){
s = 0;
for(int i = 0, ed = (1 << 2); i < ed; i++){
int ma = -1e9, mi = 1e9;
for(int j = 0, s; j < n; j++){
if(j == x) continue;
int sum = 0;
for(int k = 0; k < 2; k++){
if(i >> k & 1) sum -= points[j][k];
else sum += points[j][k];}
if(sum > ma) ma = sum;
if(sum < mi) mi = sum;
}
if(ma - mi > s) s = ma - mi;
}
ret = min(ret , s);
}
return ret;
}
};