1. 程式人生 > >【2017.10.28】noip賽前集訓 | T1 【差分】

【2017.10.28】noip賽前集訓 | T1 【差分】

none urn algo 技術 mil turn 現在 one 輸入格式

T1

【題目描述】

(求區間疊加最大數)有 n 頭牛,每頭牛有個喝水時間,這段時間它將 . 獨 . 占一個 Stall。現在給出每頭牛 的喝水時間段,問至少要多少個 Stall 才能滿足它們的要求。

【輸入格式】

第一行一個正整數 n。 接下來 n 行每行兩個正整數 a,b,表示每頭牛的喝水時間段

對於 100% 的數據,1≤n≤50000, 1≤ a ≤ b ≤106

【題解】

以下兩種代碼的思路是一樣的,只是實現方式不同,第一種更加簡潔吧(大概 )。

①註意:排序時,對於值相同的點,右端點排在前面。

技術分享
#include <cstdio>
#include 
<algorithm> const int MAXN = 1e7 + 7; int n, cnt = 1, ans, maxn; struct Node { int value, pos; bool operator < (Node c) { if (value != c.value) return value < c.value; else return pos < c.pos; } } node[MAXN]; int main() { freopen("a.in
", "r", stdin); freopen("a.out", "w", stdout); scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d%d", &node[cnt].value, &node[cnt + 1].value); node[cnt + 1].value++; // 將它延後一個是為了避免無法解決 |___|___| node[cnt].pos = 1
, node[cnt + 1].pos = -1; // 【接上一行】(前一個區間的右端點與後一個的左端點重合)的情況 cnt += 2; } std::sort(node + 1, node + 2 * n + 1); // for (int i = 1; i <= 2 * n; i++) { // printf("%d: %d %d\n", i, node[i].pos, node[i].value); // } for (int i = 1; i <= 2 * n; i++) { ans += node[i].pos; if (maxn < ans) maxn = ans; } printf("%d\n", maxn); return 0; }
View Code

技術分享
#include <cstdio>

const int MAXN = 1e7 + 7;

int n, a[MAXN], maxn, ans, re, x, y;

int main() {
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
    
    scanf("%d", &n);
    
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &x, &y);
        if (y > maxn) maxn = y;
        a[x]++;
        a[y + 1]--;
    }
    
    for (int i = 1; i <= maxn + 1; i++) {
        re += a[i];
        if (re > ans) ans = re; 
    }
    
    printf("%d\n", ans);
    
    return 0;
}
View Code

【2017.10.28】noip賽前集訓 | T1 【差分】