第一题:6214. 判断两个事件是否存在冲突
思路:用stoi函数来截取字符串,然后将开始时间大的和结束时间小的比较,如果满足则存在交集
class Solution { public: bool haveConflict(vector<string>& event1, vector<string>& event2) { int l1 = stoi(event1[0].substr(0, 2)) * 60 + stoi(event1[0].substr(3, 2)); int r1 = stoi(event1[1].substr(0, 2)) * 60 + stoi(event1[1].substr(3, 2)); int l2 = stoi(event2[0].substr(0, 2)) * 60 + stoi(event2[0].substr(3, 2)); int r2 = stoi(event2[1].substr(0, 2)) * 60 + stoi(event2[1].substr(3, 2)); return max(l1, l2) <= min(r1, r2); } };
思路:数据范围比较小,1k个,暴力枚举就可以,用到acwing872最大公约数
class Solution { public: int gcd(int a, int b){ return b ? gcd(b,a % b) : a; } int subarrayGCD(vector<int>& nums, int k) { int n = nums.size(); int res = 0; for (int i = 0; i < n; i ++){ int t = nums[i]; for (int j = i; j < n; j ++){ t = gcd(t, nums[j]); if (t == k){ res ++; } } } return res; } };
第三题:6216. 使数组相等的最小开销
思路:很好想出的是暴力来计算nums中各元素的权重后得到中位数,然后来进行加减,正确性未得到验证(样例以及思路感觉应该正确的),但数据范围在1e6,用long long 还是会爆掉,所以得采取更优的方法。可以将cost[i]看作对应的nums[i]出现的次数,每个数的操作一次的开销是1,然后参考acwing104货仓选址的思路,nums数组的中位数就是最优解,然后得出结果即可
class Solution { public: typedef long long LL; LL minCost(vector<int>& nums, vector<int>& cost) {\ int n = nums.size(); /*LL count = 0; LL sum = 0; for(int i = 0; i < n; i++){ count += nums[i] * cost[i]; sum += cost[i]; } LL zws = count / sum; //中位数 LL res = 0; for(int i = 0 ; i < n; i++){ res += abs(nums[i] - zws) * cost[i]; } */ vector<int> idx(n); iota(idx.begin(),idx.end(),0); sort(idx.begin(),idx.end(),[&](int i,int j){ return nums[i]<nums[j]; });//按照nums的大小顺序进行排序 int pos=0; LL sum=0; //首先最优解一定是把所有元素变成数组中的某个数 for(int i=0;i<n;i++){ sum+=cost[i]; } LL tmp=0; for(int i=0;i<n;i++){ //找中位数 if(tmp+cost[idx[i]]<=sum/2){ tmp+=cost[idx[i]]; }else{ pos=idx[i]; //存中位数在nums中的下标 break; } } LL res = 0; for(int i=0;i<n;i++){ //每个数到中位数需要的操作次数乘以这个数出现的个数 res += abs(nums[idx[i]]-nums[pos])*(LL)cost[idx[i]]; } return res; } };