題目描述:
有 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
題目分析如下:(摘自《算法競賽進階指南》)
題目中的 M 對關係帶給我們的信息實際上是牛之間身高的相對大小關係。 具體來說,我們建立一個數組 C,數組中其實全爲0。若存在一對關係指明: A 和 B 可以相互看見(設A < B),則把數組 C 中 下標爲 A + 1 到 B - 1 的數都減去1,意思是在 A 和 B 中間的牛,身高至少要比它們小 1。因爲第 P 頭牛是最高的,所以最終 C[P] 一定爲0。其他的牛與第 P 頭牛的身高差距就體現在數組 C 中。換言之,最後第 i 頭牛的身高就等於 H + C[i]。
AC代碼如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;
const int MAXN = 1e4+10;
int n, p, h, m;
int exited[MAXN];
LL c[MAXN];
// 初始數組爲0 說明高度都相同,以h爲基準進行修改
int main() {
scanf("%d %d %d %d", &n, &p, &h, &m);
int a, b;
while(m--) {
scanf("%d %d",&a, &b);
if(a > b) swap(a, b);
// 保證 a < b
if(exited[a] == b) continue;
// 在數組 exited 中查找(a, b)鍵值對是否出現
c[a+1] --, c[b]++;
// 區間內的高度降1 利用差分的性質
exited[a] = b;
// 標記(a, b)鍵值對已出現過
}
c[1] = h + c[1];
printf("%lld\n", c[1]);
for(int i = 2; i <= n; i++) {
c[i] = c[i-1] + c[i];
printf("%lld\n", c[i]);
}
return 0;
}