【2022-06-26-第299场单周赛】

总结

做题还是不能急,Q2又因为没取模WA了!

Q1.判断矩阵是否是一个 X 矩阵

直接遍历模拟。

class Solution {
public:
    bool checkXMatrix(vector<vector<int>>& g) {
        int n = g.size();
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                if((i == j || i + j == n - 1) && !g[i][j]) return false;
                else if(!(i == j || i + j == n - 1) && g[i][j]) return false;
            }
        }
        return true;
    }
};

Q2.统计放置房子的方式数

dp裸题。

class Solution {
public:
    const int M = 1000000007;
    int countHousePlacements(int n) {
        long long dp[n][4]; memset(dp, 0, sizeof(dp));
        dp[0][0] = dp[0][1] = dp[0][2] = dp[0][3] = 1;
        for(int i = 1; i < n; ++i){
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][3]) % M;
            dp[i][1] = (dp[i - 1][0] + dp[i - 1][2]) % M;
            dp[i][2] = (dp[i - 1][0] + dp[i - 1][1]) % M;
            dp[i][3] = dp[i - 1][0];
        }
        return (dp[n - 1][0] + dp[n - 1][1] + dp[n - 1][2] + dp[n - 1][3]) % M;
    }
};

Q3.拼接数组的最大分数

作差,求结果数组的最大和最小连续子序列和。

class Solution {
public:
    int maximumsSplicedArray(vector<int>& a, vector<int>& b) {
        int n = a.size();
        int sum1 = accumulate(a.begin(), a.end(), 0), sum2 = accumulate(b.begin(), b.end(), 0);
        //int pa[n + 1], pb[n + 1]; pa[0] = pb[0] = 0;
        //for(int i = 0; i < n; ++i) pa[i + 1] = pa[i] + a[i], pb[i + 1] = pb[i] + b[i];
        int dif[n];
        for(int i = 0; i < n; ++i){
            dif[i] = a[i] - b[i];
        }
        int dp1[n + 1], dp2[n + 1]; dp1[0] = dp2[0] = 0;
        for(int i = 0; i < n; ++i){
            if(dp1[i] <= 0) dp1[i + 1] = dif[i];
            else dp1[i + 1] = dif[i] + dp1[i];
            if(dp2[i] >= 0) dp2[i + 1] = dif[i];
            else dp2[i + 1] = dif[i] + dp2[i];
        }
        int mi = *min_element(dp2, dp2 + n + 1), mx = *max_element(dp1, dp1 + n + 1);
        return max(sum1 - mi, sum2 + mx);
    }
};

Q4.从树中删除边的最小分数

题目静心自己想好了,浪费了太多时间。
将0结点当作树的根结点,从这颗有根树上分离出两个子树。利用异或运算的性质进行逐个计算。

class Solution {
public:
    bool son[1010][1010];
    int sum[1010], vis[1010];
    int minimumScore(vector<int>& a, vector<vector<int>>& eg) {
        int n = a.size();
        vector<int> adj[n], child[n];
        for(int i = 0; i < n; ++i) sum[i] = a[i], son[i][i] = true;
        for(auto &e : eg){
            adj[e[0]].push_back(e[1]);
            adj[e[1]].push_back(e[0]);
        }

        queue<int> q;
        q.push(0); vis[0] = 1;
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(auto &v : adj[u]){
                if(!vis[v]){
                    child[u].push_back(v);
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }

        function<void(int)> helper = [&](int idx){
            for(auto &i : child[idx]){
                helper(i);
                sum[idx] ^= sum[i];
                for(int j = 0; j < n; ++j) son[idx][j] |= son[i][j];
            }
        };
        helper(0);

        int ret = INT_MAX;
        for(int i = 1; i < n; ++i) for(int j = i + 1; j < n; ++j){
            int x, y, z;
            if(!son[i][j] && !son[j][i]){
                x = sum[i];
                y = sum[j];
                z = sum[0] ^ x ^ y;
            }
            else if(son[i][j]){
                y = sum[j];
                x = sum[i] ^ sum[j];
                z = sum[0] ^ sum[i];
            }
            else if(son[j][i]){
                x = sum[i];
                y = sum[j] ^ sum[i];
                z = sum[0] ^ sum[j];
            }
            ret = min(ret, max(x, max(y, z)) - min(x, min(y, z)));
        }
        
        return ret;
        
    }
};
posted on 2022-06-27 22:24  damnglamour  阅读(27)  评论(0)    收藏  举报