LeetCode第 322 场周赛

1.回环句

回环句

Solution

class Solution {
public:
    bool isCircularSentence(string sentence) {
                int n = sentence.size(), i = 0;
        if (sentence[0] != sentence[n - 1]) return false;

        for (int i = 0; i < n; i++) {
            if (sentence[i] == ' ' && sentence[i - 1] != sentence[i + 1]) 
                return false;
        }
        return true;
    }
};

2.划分技能点相等的团队

划分技能点相等的团队

Solution

class Solution {
public:
    long long dividePlayers(vector<int>& skill) {
        long long sum = accumulate(skill.begin(),skill.end(),0);
        int n = skill.size() / 2;
        long long t = sum / n;
        if(sum % n != 0) return -1;
        sort(skill.begin(),skill.end());
        long long ans = 0;
        vector<long long> book(1005,0);
        for(int i = 0;i < skill.size();i++){
            int p = skill[i];
            book[p]++;
        }
        for(int i = 0;i < n;i++){
            long long p = skill[i];
            if(book[t - p] == 0){
                return -1;
            }
            ans += (long long)(p * (t - p));
            book[p]--;
            book[t - p]--;
        }
        return ans;
    }
};

3.两个城市间路径的最小分数

两个城市间路径的最小分数

Solution

class Solution {
public:
    int minScore(int n, vector<vector<int>>& roads) {
        //建图
        vector<int> e[n+1], v[n+1];
        for(auto road : roads){
            e[road[0]].push_back(road[1]);
            v[road[0]].push_back(road[2]);
            e[road[1]].push_back(road[0]);
            v[road[1]].push_back(road[2]);
        }
        int ans = INT_MAX;
        queue<int>q;
        bool vis[n+1];
        memset(vis,0,sizeof(vis));
        q.push(1),vis[1] = true;
        while(!q.empty()){
            int sn = q.front();q.pop();            
            for (int i = 0; i < e[sn].size(); i++) {
                // 枚举连接 sn 的所有边并更新答案
                ans = min(ans, v[sn][i]);
                int fn = e[sn][i];
                if (vis[fn]) continue;
                q.push(fn); vis[fn] = true;
            }
        }
        return ans;
    }
};

4.将节点分成尽可能多的组

将节点分成尽可能多的组

Solution

class Solution {
public:
    int magnificentSets(int n, vector<vector<int>>& edges) {
        vector<int> e[n + 1];
        for (auto &edge : edges) {
            e[edge[0]].push_back(edge[1]);
            e[edge[1]].push_back(edge[0]);
        }

        // mp[i] 表示 i 代表的连通块的答案
        unordered_map<int, int> mp;

        // 以 S 作为 BFS 的起点
        // 以连通块中编号最小的点 mn 为代表
        // 把这个连通块的解记到 mp[mn] 里
        auto bfs = [&](int S) {
            int mn = S;
            queue<int> q;
            int dis[n + 1];
            memset(dis, 0, sizeof(dis));
            q.push(S); dis[S] = 1;
            while (!q.empty()) {
                int sn = q.front(); q.pop();
                mn = min(mn, sn);
                for (int fn : e[sn]) {
                    if (dis[fn]) continue;
                    q.push(fn);
                    dis[fn] = dis[sn] + 1;
                }
            }

            int &ret = mp[mn];
            // 检查分组的合法性
            for (int i = 1; i <= n; i++) if (dis[i]) for (int fn : e[i]) if (abs(dis[i] - dis[fn]) != 1) return;
            // 求最大距离
            for (int i = 1; i <= n; i++) if (dis[i]) ret = max(ret, dis[i]);
        };

        // 枚举以每个点作为 BFS 的起点,并更新所属连通块的答案
        for (int i = 1; i <= n; i++) bfs(i);

        int ans = 0;
        // 枚举所有连通块
        for (auto it = mp.begin(); it != mp.end(); it++) {
            // 只要有一个连通块无解就无解
            if (it->second == 0) return -1;
            // 否则答案就是所有连通块的解的总和
            ans += it->second;
        }
        return ans;
    }
};
posted @ 2023-01-06 00:00  TTS-S  阅读(16)  评论(0编辑  收藏  举报