hdu6860 Fluctuation Limit
阿新 • • 發佈:2020-08-14
題目連結: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\n",res[n].le);
63 }
64
65 }
66
67 return 0;
68 }