【2022/07/17-第302场单周赛】

总结
手速场。
Q1.数组能形成多少数对
根据数据范围,用哈希表一对一对找即可。
class Solution {
public:
vector<int> numberOfPairs(vector<int>& a) {
int h[110]; memset(h, 0, sizeof(h));
for(auto i : a) ++h[i];
vector<int> ret{0, 0};
for(int i = 0; i < 110; ++i){
ret[0] += h[i] / 2;
ret[1] += h[i] & 1;
}
return ret;
}
};
Q2.数位和相等数对的最大和
以数位和为键,用优先队列存储每个数位和下的所有数,然后找到最大值。
class Solution {
public:
int maximumSum(vector<int>& a) {
map<int, priority_queue<int, vector<int>, less<int> > > mp;
for(auto i : a){
int t = 0, x = i;
while(x){
t += x % 10;
x /= 10;
}
mp[t].push(i);
}
int ret = -1;
for(auto &i : mp){
if(i.second.size() >= 2){
int x = i.second.top(); i.second.pop();
x += i.second.top();
ret = max(ret, x);
}
}
return ret;
}
};
Q3.裁剪数字后查询第 K 小的数字
对于每个查询都排序,然后得到结果。
class Solution {
public:
vector<int> smallestTrimmedNumbers(vector<string>& a, vector<vector<int>>& q) {
int n = a.size(), m = a[0].size();
map<string, vector<int>> mp;
for(int i = 0; i < n; ++i){
mp[a[i]].push_back(i);
}
vector<int> ret;
for(auto &i : q){
int k = i[0], len = i[1];
sort(a.begin(), a.end(), [&](const string &s, const string &t){
for(int j = m - len; j < s.size(); ++j){
if(s[j] < t[j]) return true;
if(s[j] > t[j]) return false;
}
return mp[s] < mp[t];
});
string ts = a[k - 1];
int pre = 0;
for(int j = k - 2; j >= 0; --j){
if(a[j] == ts) ++pre;
else break;
}
ret.push_back(mp[ts][pre]);
}
return ret;
}
};
先排好序再查询
class Solution {
public:
vector<int> smallestTrimmedNumbers(vector<string>& a, vector<vector<int>>& q) {
int n = a[0].size();
vector<int> v, ret;
for(int i = 0; i < a.size(); ++i) v.push_back(i);
vector<string> mp = a;
unordered_set<int> st;
for(auto &i : q) st.insert(i[1]);
for(int i = 0; i < a.size(); ++i) mp[i] = a[i];
vector<int> b[n + 1];
for(auto & i : st){
sort(v.begin(), v.end(), [&](int x, int y){
for(int j = n - i; j < n; ++j){
if(mp[x][j] < mp[y][j]) return true;
else if(mp[x][j] > mp[y][j]) return false;
}
return x < y;
});
b[i] = v;
}
for(auto &i : q){
ret.push_back(b[i[1]][i[0] - 1]);
}
return ret;
}
};
Q4.使数组可以被整除的最少删除次数
找到第二个数组最大公因数,对第一个数组排序,然后逐个判断即可。
class Solution {
public:
int minOperations(vector<int>& a, vector<int>& d) {
int x = d[0], ret = 0;
function<int(int, int)> gcd = [&](int a, int b){
if(b > a) swap(a, b);
return a % b == 0 ? b : gcd(b, a % b);
};
for(int i = 1; i < d.size(); ++i) x = gcd(x, d[i]);
sort(a.begin(), a.end());
for(auto i : a){
if(x % i == 0) return ret;
else ++ret;
}
return -1;
}
};
浙公网安备 33010602011771号