【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;
    }
};
posted on 2022-08-02 15:20  damnglamour  阅读(25)  评论(0)    收藏  举报