LeetCode63双周赛

https://leetcode-cn.com/contest/biweekly-contest-63/

  1. 使每位学生都有座位的最少移动次数
    // 贪心
    class Solution {
    public:
        int minMovesToSeat(vector<int>& seat, vector<int>& stu) {
            sort(seat.begin(), seat.end());
            sort(stu.begin(), stu.end());
            
            int ans = 0;
            for (int i = 0; i < seat.size(); i++) {
                ans += abs(seat[i] - stu[i]);
            }
            
            return ans;
        }
    };
  1. 如果相邻两个颜色均相同则删除当前颜色
    // 遍历统计
    class Solution {
    public:
        bool winnerOfGame(string c) {
            int n = c.length();
            int a = 0, b = 0;
            for (int i = 1; i < n - 1; i++) {
                if (c[i] == 'A' && c[i - 1] == 'A' && c[i + 1] == 'A') {
                    a++;
                }
                if (c[i] == 'B' && c[i - 1] == 'B' && c[i + 1] == 'B') {
                    b++;
                }
            }
            if (a <= b) {
                return false;
            } else {
                return true;
            }
        }
    };
  1. 网络空闲的时刻
    // 单源点最短路,后求时间
    const int maxn = 1e6;
    
    struct Edge {
        int from, to, dist;
        Edge(int f, int t, int d): from(f), to(t), dist(d) {}
    };
    
    struct HeapNode {
        int d, u;
        bool operator<(const HeapNode& rhs) const {
            return d > rhs.d;
        }
    };
    
    struct Dijkstra {
        int n, m;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool done[maxn];
        int d[maxn];
        int p[maxn];
        
        void init(int x) {
            n = x;
            for (int i = 0; i < n; i++) G[i].clear();
            edges.clear();
        }
        
        void AddEdge(int from, int to, int dist) {
            edges.emplace_back(from, to, dist);
            m = edges.size();
            G[from].push_back(m - 1);
        }
        
        void dijkstra(int s) {
            priority_queue<HeapNode> Q;
            for (int i = 0; i < n; i++) d[i] = INT_MAX;
            d[s] = 0;
            memset(done, 0, sizeof done);
            Q.push(HeapNode{0, s});
            while (!Q.empty()) {
                auto x = Q.top(); Q.pop();
                int u = x.u;
                if (done[u]) continue;
                done[u] = true;
                for (int i = 0; i < G[u].size(); i++) {
                    Edge& e = edges[G[u][i]];
                    if (d[e.to] > d[u] + e.dist) {
                        d[e.to] = d[u] + e.dist;
                        p[e.to] = G[u][i];
                        Q.push(HeapNode{d[e.to], e.to});
                    }
                }
            }
        }
    };
    
    class Solution {
    public:
        int networkBecomesIdle(vector<vector<int>>& edges, vector<int>& p) {
            Dijkstra dd;
            int n = p.size();
            dd.init(n);
            for (auto& e: edges) {
                dd.AddEdge(e[0], e[1], 1);
                dd.AddEdge(e[1], e[0], 1);
            }
            
            dd.dijkstra(0);
            int ans = 0;
            
            for (int i = 1; i < p.size(); i++) {
                //cout << dd.d[i] << endl;
                int tmp = dd.d[i] * 2;
    			// 发送到接收经过tmp秒,从第一秒开始重新发送,(tmp - 1)秒发送了(tmp - 1) / p[i]条信息,故发送的总时间为(tmp - 1) / p[i] * p[i] + tmp
                ans = max(ans, (tmp - 1) / p[i] * p[i] + tmp);
            }
            // 下一秒网络清净
            return ans + 1;
        }
    };
  1. 两个有序数组的第 K 小乘积
    // 参考评论区做法
    // 按正负分为a1,a2,b1,b2
    class Solution {
    public:
        using ll = long long;
        // <= t 的个数
        ll f(vector<int> x, vector<int> y, ll t) {
            ll ret = 0, n = x.size(), m = y.size();
            for (int i = 0, j = m - 1; i < n; i++) {
                while (j >= 0 && (ll)x[i] * y[j] > t) j--;
                ret += (j + 1);
            }
            return ret;
        }
    
        long long kthSmallestProduct(vector<int>& nums1, vector<int>& nums2, long long k) {
            vector<int> a1, a2, b1, b2;
            for (int i = 0; i < nums1.size(); i++) {
                if (nums1[i] < 0) {
                    a1.push_back(-nums1[i]);
                }
                if (nums1[i] > 0) {
                    a2.push_back(nums1[i]);
                }
            }
            for (int i = 0; i < nums2.size(); i++) {
                if (nums2[i] < 0) {
                    b1.push_back(-nums2[i]);
                }
                if (nums2[i] > 0) {
                    b2.push_back(nums2[i]);
                }
            }
    
            reverse(a1.begin(), a1.end()), reverse(b1.begin(), b1.end());
            ll n = nums1.size(), m = nums2.size();
            ll alen1 = a1.size(), alen2 = a2.size();
            ll blen1 = b1.size(), blen2 = b2.size();
    
            if (k <= alen1 * blen2 + blen1 * alen2) {
                ll l = 0, r = 1e10;
                // 小于0计算倒数
                k = alen1 * blen2 + alen2 * blen1 - k + 1;
                while (l < r) {
                    ll mid = l + r >> 1;
                    ll f1 = f(a1, b2, mid) + f(a2, b1, mid);
                    if (f1 >= k) r = mid;
                    else l = mid + 1;
                }
                return -l;
            } else if (k > n * m - alen1 * blen1 - alen2 * blen2) {
                ll l = 0, r = 1e10;
                // 减去<= 0的数
                k -= (n * m - alen1 * blen1 - alen2 * blen2);
                while (l < r) {
                    ll mid = l + r >> 1;
                    ll f1 = f(a1, b1, mid) + f(b2, a2, mid);
                    if (f1 >= k) r = mid;
                    else l = mid + 1;
                }
                return l;
            }
            return 0;
        }
    };
posted @ 2021-11-26 15:34  Wang~ze君  阅读(24)  评论(0)    收藏  举报