• [hihocoder][Offer收割]编程练习赛50


    循环数组

    计算a[i]的前缀和s[i],计算l[i]为1~i-1中最小的s值,r[i]为i~n中最大的s值。

    则a[i]~a[n]满足性质的条件为r[i]-s[i-1]>0,a[1]~a[i-1]满足性质的条件为l[i]+s[n]-s[i-1]>0

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<functional>
    #include<math.h>
    //#include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    typedef queue<int> QI;
    
    
    void makedata() {
        freopen("input.txt", "w", stdout);
        fclose(stdout);
    }
    
    lint a[110000], s[110000], l[110000], r[110000];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        //makedata();
        std::ios::sync_with_stdio(0), cin.tie(0);
        int n;
        cin >> n;
    
        for(int i = 1; i <= n; i++) cin >> a[i];
    
        s[1] = a[1];
    
        for(int i = 2; i <= n; i++) s[i] = s[i - 1] + a[i];
    
        l[1] = 0, l[2] = s[1];
    
        for(int i = 3; i <= n; i++) l[i] = min(l[i - 1], s[i - 1]);
    
        r[n] = s[n];
    
        for(int i = n - 1; i >= 1; i--) r[i] = min(s[i], r[i + 1]);
    
        for(int i = 1; i <= n; i++) {
            if((r[i] - s[i - 1] > 0) && (s[n] - s[i - 1] + l[i] > 0)) {
                cout << i << endl;
                return 0;
            }
        }
    
        cout << -1 << endl;
        return 0;
    }
    View Code

    座位问题

    根据题目要求,对于一段区间为l~r的连续空座位,其中最优先的位置应为(l+r)/2。对于多段连续的空座位,选择其中长度最长的那一段,如果有多段都是最长的,选择开始位置最小的那一段。坐下后一段可能变为两段、一段或零段,用一个小根堆维护这些段,新来的直接插在堆顶的段里。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<functional>
    #include<math.h>
    //#include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    typedef queue<int> QI;
    
    
    void makedata() {
        freopen("input.txt", "w", stdout);
        fclose(stdout);
    }
    class segment {
    public:
        int l, r;
        bool operator <(const segment & s) const {
            if(r - l < s.r - s.l) return true;
    
            if(r - l > s.r - s.l) return false;
    
            return l > s.l;
        }
    };
    priority_queue<segment> q;
    int a[110000];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        //makedata();
        std::ios::sync_with_stdio(0), cin.tie(0);
        int n, m, k;
        cin >> n >> m >> k;
    
        for(int i = 1; i <= m; i++) cin >> a[i];
    
        a[0] = 0, a[m + 1] = n + 1;
    
        for(int i = 1; i <= m + 1; i++) {
            //a[i - 1] + 1, a[i] - 1
            if(a[i - 1] + 1 <= a[i] - 1) {
                segment s;
                s.l = a[i - 1] + 1;
                s.r = a[i] - 1;
                q.push(s);
            }
        }
    
        for(int i = 0; i < k; i++) {
            segment s = q.top(), tmp;
            q.pop();
            int x = (s.l + s.r) / 2;
            cout << x << endl;
    
            if(s.l <= x - 1) {
                tmp.l = s.l, tmp.r = x - 1;
                q.push(tmp);
            }
    
            if(x + 1 <= s.r) {
                tmp.l = x + 1, tmp.r = s.r;
                q.push(tmp);
            }
        }
    
        return 0;
    }
    View Code

    末尾有最多0的乘积

    显然0的个数只与每个数中2和5的因子个数有关。

    动态规划:dp[i][j][k]表示从前i个中选出j个得到k个2时能得到的最多的5的个数,值为-1表示该状态不存在。

    dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - 1][k - b[i]] + c[i]);

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<functional>
    #include<math.h>
    //#include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    typedef queue<int> QI;
    
    
    void makedata() {
        freopen("input.txt", "w", stdout);
        fclose(stdout);
    }
    
    int dp[105][105][4000], b[105], c[105];
    lint a[105];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        //makedata();
        std::ios::sync_with_stdio(0), cin.tie(0);
        int n, m;
        cin >> n >> m;
    
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
            b[i] = c[i] = 0;
    
            while(a[i] % 2 == 0) a[i] /= 2, b[i]++;
    
            while(a[i] % 5 == 0) a[i] /= 5, c[i]++;
        }
    
        memset(dp, -1, sizeof(dp));
    
        for(int i = 0; i <= n; i++) dp[i][0][0] = 0;
    
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= i; j++) {
                for(int k = 3200; k >= 0; k--) {
                    dp[i][j][k] = dp[i - 1][j][k];
    
                    if(k >= b[i] && dp[i - 1][j - 1][k - b[i]] != -1) dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - 1][k - b[i]] + c[i]);
                }
            }
        }
    
        int ans = 0;
    
        for(int i = 0; i < 3200; i++) if(dp[n][m][i] != -1)ans = max(min(dp[n][m][i], i), ans);
    
        cout << ans << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    【leetcode刷题笔记】Best Time to Buy and Sell Stock II
    【leetcode刷题笔记】Reverse Integer
    JAVA中的NIO(二)
    标准I/O
    margin的理解
    JAVA中的NIO(一)
    IO模型
    linux网络命令
    linux用户管理命令
    linux中的帮助命令
  • 原文地址:https://www.cnblogs.com/dramstadt/p/8560412.html
Copyright © 2020-2023  润新知