题目描述
Kevin的军训时间
一年一度的军训又开始啦,Kevin作为大二学长也想掺和一脚,他看到计算机类2001班总共有N(1 ≤ N ≤ 10,000)个小萌新,他们按照1-n编号并站成一排。每个萌新都有一个正整数的身高,Kevin目测得到最高的萌新的身高H (1 ≤ H ≤ 1,000,000)和他所在位置编号I。(注意可能最高的萌新不止一个,I只是其中之一)
教官给了Kevin一个拥有R (0 ≤ R ≤ 10,000)行的列表,每行给出A,B,这表示A、B两个位置的萌新能够互相看到。(B位置萌新的身高大于等于A位置萌新的身高,且A到B之间的萌新都不比他们高)
现让你求出每个萌新最高能有多高才能满足这个列表。
Input
第1行: 空格隔开的四个整数:N, I, H , R
第2行--R+1行: 每行输入 A 和 B (1 ≤ A, B ≤ N)
Output
第1行--第n行:行 i 包含一个 i 位置萌新有可能的最大高度
Sample Input
8 1 7 6
1 2
3 4
2 4
7 6
6 8
5 8
Sample Output
7
7
6
7
7
6
5
7。
题目含义
N:n个人
I :第I个人为最高的人之一。
H:最高的人的身高
R:后面有R个条件(A的身高<=B的身高 , 在AB之间的人的身高,要比AB都小,注意题目写的不明确,是要小于,而不是小于等于)
想法
首先想到的是暴力,但是时间应该不允许。于是就想转为差分。但是,差分在updata函数之前,没有办法判断A是否真的小于等于B,万一A的身高大于B的身高怎么办?
后来看了题解,发现题解根本没有处理这个情况。想了想才发现,这种情况根本不存在。因为,如果A的身高比B的低,那说明A在两个(AA(是>A的),BB(>A))之间,而存在那么两个AA ,BB是分隔A 和B的,即如果题目给出(A , B)而且A的身高比B的身高要高,那就是这个数据不对。
另外不要忘记去重。
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<utility>
#include<map>
//题目的隐藏条件要判断清楚,比如这道题。
//在updata的过程中,不可能出现knum[a] > knum[b]的结果
//但是,我却一直在思考这个条件如果用差分应该怎么判断
using namespace std;
const int N = 1e4 + 1e2;
int cf[N];
int n , i , h , r;
map<pair<int , int> , bool> ma;
void updata(int begin , int end){
if(begin > end) swap(begin , end) ;
cf[begin+1] --;
cf[end]++;
}
int main(){
int i , j , a , b ;
cin>>n>>i>>h>>r;
for(i = 0 ; i < r ; i ++ ){
cin>>a>>b;
if(ma[make_pair(a,b)]) continue;
ma[make_pair(a,b)] = true;
updata(a , b );
}
for(i = 1 ; i <= n ; i ++ ){
cf[i] += cf[i-1];
cout<<(h + cf[i])<<endl;
}
return 0;
}