hdu 6860 Fluctuation Limit
—南昌理工学院ACM集训队
题意
给你n个范围[li,ri]和一个整数k,要求构建一个长度为n的数组ai,要求保证ai >= li && ai <= ri,并且保证相邻两个ai之间的差值的绝对值不大于k。若可以,那么输出YES并输出他的价格序列;否则出NO。
思路
根据限制条件一步步缩小ai的范围,如果第一个数字的范围是[l1,r1],那么第二个数字选择的范围就是[l1-k,r1+k]与[l2,r2]的交集。由于是相邻两个ai之间的差值的绝对值不大于k,所以不仅前一个数字的范围会影响后一个数字的范围,而且后一个数字的范围会影响前一个数字的范围。所以从头到尾缩小一遍范围,再从尾到头缩小一遍范围,若缩小范围时出现范围l>r,则不成立。因为题目只要求一种,全取范围中最低的即可。
#include <queue>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int t,n,k;
int a[100005][2];
bool f=1;
scanf("%d",&t);
while(t--)
{
f=1;//表判断,f=0表有范围不合法
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i][0],&a[i][1]);
if(i!=1&&f)
{
a[i][0]=max(a[i-1][0]-k,a[i][0]);
a[i][1]=min(a[i-1][1]+k,a[i][1]);//求交集
if(a[i][0]>a[i][1]){f=0;}//判断范围是否合法
}
}
if(f)
for(int i=n-1;i>=1;i--)
{
a[i][0]=max(a[i+1][0]-k,a[i][0]);
a[i][1]=min(a[i+1][1]+k,a[i][1]);
if(a[i][0]>a[i][1]){f=0;break;}//判断范围是否合法
}
if(f==0)printf("NO\n");
else {
printf("YES\n");
for(int i=1;i<n;i++)
{
printf("%d ",a[i][0]);
}
printf("%d\n",a[n][0]);
}
}
return 0;
}
超时了好多次,挺奔溃的,
此为赛后补的水题,赛后换的机器挺烦人的,赛后发的答案被我交上去都超时了,挺无语的,最后只能自己写,我能想到的都优化了