Codeforce 1704 B. Luke is a Foodie

Codeforce 1704 B. Luke is a Foodie

题意

大意就是给你正整数n,x;

然后给出n个正整数,a[1],a[2],a[3]…a[n];

对于每一个a[i] ( 1 ≤ i ≤ n) ,我们自己给出一个v , 使得

​ | v − a[i] | ≤ x

这个v最开始是我们自己确定的,我们需要确定一个合适的v,使得这个区间[ v - x , v + x ] 要尽可能多地囊括数个a[i];

这个v可以人为地变动,我们需要给出一个ans,ans是最小变动v的次数,使得这个区间[ v - x , v + x ] 囊括住所有的a;

思路

我们要先想明白一个事情,

对于a[1]和a[2],要怎么样子找一个v,使得区间[ v - x , v + x ],使得它囊括a[1]和a[2];

看图:
请添加图片描述

绿色部分是[a1 - x , a1 + x ];

蓝色部分是[a2 - x , a2 + x ];

它们重合的部分就是v可以取到的范围;

道理很简单:想象甲和乙的手臂是一样长的;

他们分别把手臂张开,然后两个人的手臂搭在一起;

此时来了一个丙,他的手臂跟甲乙一样长;

丙只要站在手臂重合区,就可以碰到甲和乙;

我们只要遍历a[i] 和 a[i+1],找出那个v存在的区间——上图中红色的部分,看看能不能它能不能囊括所有的a;

如果不行,更换一个新的区间,ans++,依次类推下去,直到所有的a都被遍历过一遍;

最后输出ans的值

AC代码

#include<bits/stdc++.h>
using namespace std;

const int N = 2e6+10;

int n,x;

int a[N];

void solve(){
	cin>>n>>x;
	for(int i = 0 ; i < n ; i ++){
		cin>>a[i];
	}
	
	int ans = 0 ;
	int left = a[0] - x ,right = a[0] + x;
	
	//严格保证left < right 
	for(int i = 1 ; i < n ; i ++){
		int tmpl = a[i] - x ,tmpr = a[i] + x;
		if(right < tmpl || left > tmpr){
			ans ++ ;
			left = tmpl;
			right = tmpr;
			//完全没有重合的区间,取最新那个点作为新的判定区; 
		}else{
			left = max(left ,tmpl);
			right = min(right , tmpr);
			//更新区间; 
		}
	}
	cout<<ans<<endl;
}

int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	} 
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值