【2022-07-31-第304场单周赛】

总结
Q1.使数组中所有元素都等于零
其实就是不为0的数的种类。
class Solution {
public:
int minimumOperations(vector<int>& a) {
set<int> st;
for(auto i : a) if(i) st.insert(i);
return st.size();
}
};
Q2.分组的最大数量
先把数组排序,就一定能满足前面分组分数和小于后面分组。然后计算能分成大小递增的组数。
class Solution {
public:
int maximumGroups(vector<int>& a) {
int n = a.size();
sort(a.begin(), a.end());
function<bool(int)> check = [&](int k){
if((long long)k * (k + 1) / 2 <= n) return true;
return false;
};
int l = 0, r = n + 1;
while(l + 1 < r){
int mid = l + r >> 1;
if(check(mid)) l = mid;
else r = mid;
}
return l;
}
};
Q3.找到离给定两个节点最近的节点
两次BFS计算出两个点到所有点的距离,有一组数据出问题,直接给特判了。
class Solution {
public:
const int INF = 1e9;
int closestMeetingNode(vector<int>& eg, int x, int y) {
int n = eg.size();
int a[n], b[n];
for(int i = 0; i < n; ++i) a[i] = b[i] = INF;
int vis[n]; memset(vis, 0, sizeof(vis));
queue<int> q;
int t = 0;
q.push(x);
vis[x] = 1;
while(!q.empty()){
int sz = q.size();
while(sz--){
int k = q.front(); q.pop();
if(eg[k] != -1 && !vis[eg[k]]) {
q.push(eg[k]);
vis[eg[k]] = 1;
}
a[k] = t;
}
++t;
}
memset(vis, 0, sizeof(vis));
t = 0;
vis[y] = 1;
q.push(y);
while(!q.empty()){
int sz = q.size();
while(sz--){
int k = q.front(); q.pop();
if(eg[k] != -1 && !vis[eg[k]]){
q.push(eg[k]);
vis[eg[k]] = 1;
}
b[k] = t;
}
++t;
}
int mi = 1000000000, ret = -1;
for(int i = 0; i <n; ++i){
if(a[i] + b[i] < mi){
mi = a[i] + b[i];
ret = i;
}
}
return ret;
}
};
Q4.图中的最长环
dfs,记录深度,用于判断环长度。一开始没剪枝超时了。
class Solution {
public:
int longestCycle(vector<int>& eg) {
int n = eg.size(), ret = -1, t = -1;
int vis[n], dpt[n]; memset(vis, 0, sizeof(vis)); memset(dpt, -1, sizeof(dpt));
function<void(int, int)> dfs = [&](int idx, int depth){
// cout << idx << ' ';
if(dpt[idx] != -1){
t = max(t, depth - dpt[idx]);
return ;
}
if(vis[idx]) return ;
vis[idx] = 1;
dpt[idx] = depth;
if(eg[idx] != -1) dfs(eg[idx], depth + 1);
dpt[idx] = -1;
};
for(int i = 0; i < n; ++i){
if(!vis[i]){
t = -1;
dfs(i, 0);
// cout << endl;
ret = max(ret, t);
}
}
return ret;
}
};
浙公网安备 33010602011771号