2020 杭电多校 第八场 1006 Fluctuation Limit 区间缩小

2020 杭电多校 第八场 1006 Fluctuation Limit 区间缩小

题意

给你n个价格范围l,r,问最后没组价格的上下浮动能不能不超过k

题解

如果 i 是在 [l, r] 范围内, 那么 i + 1 必须要在 [l-k, r + k] 范围内.这是因为如果 i + 1 选了范围外的值, i 就无解了.
这样可以从左往右, 把左边的约束带到右边.再从右往左做一遍.最后剩下的区间应该就是可行域.因为题目只要求一种方案, 全部选最低的即可.复杂度 O(n).

AC代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define PI acos(-1)
const int maxn = 1e5+5;
const ll mod = 1e9;
const double eps = 1e-6L;
ll n,k;
struct node
{
     
    ll l,r;
} a[maxn];
int main()
{
     
    int T;
    scanf("%d",&T);
    while(T--)
    {
     
        scanf("%lld %lld",&n,&k);
        for(int i=0; i<n; i++)
        {
     
            scanf("%lld %lld",&a[i].l,&a[i].r);
        }
        ll left=a[0].l,right = a[0].r;
        bool flag = true;
        for(int i=1; i<n; i++)
        {
     
            left = left-k;
            right = right+k;
            a[i].l = max(a[i].l,left);
            a[i].r = min(a[i].r,right);
            left = a[i].l;
            right = a[i].r;
            if(a[i].l>a[i].r)
            	flag = false;
        }
        left=a[n-1].l,right = a[n-1].r;
        for(int i=n-2; i>=0; i--)
        {
     
            left = left-k;
            right = right+k;
            a[i].l = max(a[i].l,left);
            a[i].r = min(a[i].r,right);
            left = a[i].l;
            right = a[i].r;
            if(a[i].l>a[i].r)
            	flag = false;
        }
        if(!flag)	puts("NO");
        else
        {
     
        	puts("YES");
        	for(int i=0; i<n; i++)
        	{
     
        		if(i)printf(" ");
				printf("%d",a[i].l);
			}
			puts("");
		}
    }
    return 0;
}
/*

*/

你可能感兴趣的:(补题库)