题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6860
题目大意:给定n个区间[ l[i] , r[i] ]以及int型的k,试求出是否存在一个序列res[n],满足 l[i] <= res[i] <= r[i],且相邻两个res[i]与res[i + 1]之差不超过k。
反省:比赛的时候只正向推了一遍。然后就在研究怎么筛。这题做不出真的不应该啊。相邻的区间是相互限制的,明白这一点就应该双向处理。最后得到的区间里任取即可。
*转载请附本文链接 谢谢
1 #include<iostream>
2 #include<algorithm>
3 #include<cstring>
4 #include<cmath>
5
6 #define INF 1e9
7 #define ll long long
8 using namespace std;
9
10 const int maxn = 1e5 + 10;
11
12 int n;
13 ll k;
14 ll l[maxn], r[maxn];
15
16 struct node
17 {
18 ll le;
19 ll ri;
20 };
21
22 int main(){
23 int T;scanf("%d",&T);
24 while(T--)
25 {
26 scanf("%d %lld",&n,&k);
27 for(int i = 1 ; i <= n ; i++){
28 scanf("%lld%lld",&l[i],&r[i]);
29 }
30 node res[maxn];
31 int flag = 0;
32 res[0].le = -INF;
33 res[0].ri = INF;
34
35 for(int i = 1 ; i <= n ; i++){
36 if(l[i] > res[i - 1].ri + k || r[i] < res[i - 1].le - k || res[i - 1].le > res[i - 1].ri){
37 goto NO;
38 }
39 res[i].le = max(l[i], res[i - 1].le - k);
40 res[i].ri = min(r[i], res[i - 1].ri + k);
41 }
42
43 res[n + 1].le = -INF;
44 res[n + 1].ri = INF;
45
46 for(int i = n ; i >= 1 ; i--){
47 if(l[i] > res[i + 1].ri + k || r[i] < res[i + 1].le - k || res[i + 1].ri < res[i + 1].le){
48 goto NO;
49 }
50 res[i].le = max(res[i].le, res[i + 1].le - k);
51 res[i].ri = min(res[i].ri, res[i + 1].ri + k);
52 }
53
54 if(flag){
55 NO:
56 cout << "NO" << endl;
57 }else{
58 cout << "YES" << endl;
59 for(int i = 1 ; i < n ; i++){
60 printf("%lld ",res[i].le);
61 }
62 printf("%lld
",res[n].le);
63 }
64
65 }
66
67 return 0;
68 }