差分:最高的牛詳解

題目描述:

有 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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章