1. 程式人生 > 實用技巧 >hdu6860 Fluctuation Limit

hdu6860 Fluctuation Limit

題目連結: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 }