1. 程式人生 > >P3029 [USACO11NOV]牛的陣容Cow Lineup

P3029 [USACO11NOV]牛的陣容Cow Lineup

【問題描述】

農民約翰僱一個專業攝影師給他的部分牛拍照。由於約翰的牛有好多品種,他喜歡他的照片包含每

個品種的至少一頭牛。

約翰的牛都站在一條沿線的不同地方, 每一頭牛由一個整數位置 X_i以及整數品種編號 ID_i表示。

約翰想拍一張照片,這照片由沿線的奶牛的連續範圍組成。照片的成本與規模相當,這就意味著,在一

系列照片中的最大和最小 X 座標的差距決定了照片的成本。

請幫助約翰計算最小的照片成本,這些照片中有每個不同的品種的至少一頭牛,沒有兩頭牛願意站

在同一個地點的。

【輸入格式】

第 1 行:牛的數量 N;

第 2..1+N 行:每行包含 2 個以空格分隔的正整數 X_i 和 ID_i;意義如題目描述;

【輸出格式】

輸出共一行,包含每個不同品種 ID 的照片的最低成本。

【輸入樣例】

6 25 7 26 1 15 1 22 3 20 1 30 1 【輸出樣例】

4 【輸入說明】在不同的座標點 25,26,15,22,20,30 中有六頭牛

【輸出說明】在約翰的牛中,從 X=22 到 X=26(整個規模為 4)包含了每個的不同品種的 ID 3,7 和 1。

【資料規模】

對於 50%的資料: 1≤N≤300;

對於 100%的資料:1≤N≤50,000;0≤X_i≤1,000,000,000;1≤ID_i≤1,000,000,000;

AC程式碼:

// luogu-judger-enable-o2
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>

using namespace std;

struct node {
    int pos;
    int id;
//    bool operator > (const node &p) {
//        return pos > p.pos;
//    }
    bool operator < (const node &p) const {
        return pos < p.pos;
    }
};

const int maxn = 50000 + 10;
const int inf = 0x3f3f3f3f;

//priority_queue<node, vector<node >, greater<node > > que;
queue<node > que;
map<int, int> mp;
node ac[maxn + 10];
int vis[maxn + 10];
int cnt = 0;
int sum = 0;

int main() {
    ios::sync_with_stdio(false);
    cin.tie();
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> ac[i].pos >> ac[i].id;
        if(mp.count(ac[i].id)) {
            ac[i].id = mp[ac[i].id];continue;
        }
        cnt ++;
        mp.insert(map<int, int >::value_type(ac[i].id, cnt));
        ac[i].id = cnt;
    }
//    for (int i = 1; i <= n; i++) {
//        cout << ac[i].id << " " << ac[i].pos << endl;
//    }
    sort(ac+1, ac+1+n);
    int ans = inf;
    for (int i = 1; i <= n; i++) {
        que.push(ac[i]);
        int id = ac[i].id;
        int pos = ac[i].pos;
        if(!vis[id]) {
            sum ++;
        }
        vis[id] ++;
        while(!que.empty() && vis[que.front().id] > 1) {
            vis[que.front().id] --;
            que.pop();

        }
        if(sum == cnt) {
            ans = min(ans, que.back().pos - que.front().pos);
        }
    }
    cout << ans << endl;
    return 0;
}