1. 程式人生 > >[hihocoder][Offer收割]編程練習賽50

[hihocoder][Offer收割]編程練習賽50

close DC 編程 fun splay 優先 endif cin max

循環數組

計算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

[hihocoder][Offer收割]編程練習賽50