【算法競賽進階指南】最高的牛(差分+前綴和)

題目描述:

有 N 頭牛站成一行,被編隊爲1、2、3…N,每頭牛的身高都爲整數。
當且僅當兩頭牛中間的牛身高都比它們矮時,兩頭牛方可看到對方。
現在,我們只知道其中最高的牛是第 P 頭,它的身高是 H ,剩餘牛的身高未知。
但是,我們還知道這羣牛之中存在着 M 對關係,每對關係都指明瞭某兩頭牛 A 和 B 可以相互看見。
求每頭牛的身高的最大可能值是多少。

輸入格式

第一行輸入整數N,P,H,M,數據用空格隔開。

接下來M行,每行輸出兩個整數 A 和 B ,代表牛 A 和牛 B 可以相互看見,數據用空格隔開。

輸出格式

一共輸出 N 行數據,每行輸出一個整數。
第 i 行輸出的整數代表第 i 頭牛可能的最大身高。

數據範圍

1≤N≤10000,
1≤H≤1000000,
1≤A,B≤10000,
0≤M≤10000

輸入樣例:

9 3 5 5
1 3
5 3
4 3
3 7
9 8

輸出樣例:

5
4
5
3
4
4
5
5
5

注意:

此題中給出的關係對可能存在重複

這道題會用到map和pair的一些小知識,大家可以瞭解一下,在這不過多闡述,貼出來兩篇寫的很好的博客~
【C++ map用法總結】
【C++ pair的基本用法總結】

思路分析: 這道題的重點就是如何處理讓兩頭牛能相互看見的問題。
首先我們可以想到要是兩頭牛能相互看到則要是兩頭牛中間的牛牛們的身高都要至少低1,而又要滿足中間的牛牛們的身高都最高,則只減1。
則我們可以開一個D[i]數組來表示第i頭牛比最高的牛矮多少; 然後對給出的關係(A,B)進行操作,讓 d[A+1]–,d[B]++ 可以實現僅僅對區間內的牛們操作。

AC代碼:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
map<pair<ll,ll>,ll> q;
ll n,p,h,m,i;
ll c[10100],d[10100];
//D[i]表示第i頭牛比最高的牛矮多少; 
int main()
{
    cin>>n>>p>>h>>m;
    for (i=1;i<=m;i++)
    {
        ll A,B;
        cin>>A>>B;
        if (A>B)
            swap(A,B);
        if (!q[make_pair(A,B)])
		//這個區間對象沒有出現過,本題數據可能重複,要判重;  
        {
            q[make_pair(A,B)]=1;//首次出現則標記爲1
            d[A+1]--,d[B]++;//僅僅對區間內牛的身高操作 
        }
    }
    for(i=1;i<=n;i++)
        c[i]=c[i-1]+d[i];
    for(i=1;i<=n;i++)
        cout<<c[i]+h<<endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章