題意描述
有 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
思路
這道題的思路很容易想出來,就是不斷的構造。先將每個牛的高度都設爲最高的牛的高度,然後根據題意描述將[l,r]中區間的高度減1,。需要注意的是,由於題目中要求的是儘可能的最大,所以有可能兩頭牛之間已經能夠看見,這時就不用相減了,因爲這個原因WA了幾次。可以使用一個標記數組,每次相減後,都將那個區間打上標記,然後每次構造時判斷區間內是否全部打上標記即可。
AC代碼
#include<iostream>
#include<algorithm>
#include<cmath>
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int INF=1e9+7;
int a[maxn];
bool flag[maxn];
int n,p,h,m;
int main()
{
IOS;
cin>>n>>p>>h>>m;
for(int i=1;i<=n;i++) a[i]=h;
while(m--){
int x,y;
bool t=true;
cin>>x>>y;
if(x>y) swap(x,y);
for(int i=x+1;i<y;i++){
if(flag[i]!=true) t=false;
}
if(t) continue;
for(int i=x+1;i<y;i++){
a[i]--;
}
for(int i=x+1;i<y;i++){
flag[i]=true;
}
}
for(int i=1;i<=n;i++) cout<<a[i]<<endl;
return 0;
}