【vijos】1763 Wormhole(贪心)

https://vijos.org/p/1764

首先第一个虫洞一定是建在1号点。

证明如下:

假设一个虫洞在a,一个在b,a<b,那么走到k点的最短距离为

min{|x1-xk|, |x1-xa|+|xj-xk|},注意到|x1-xa|+|xj-xk|中的|x1-xa|是常数,而且对后一个|xj-xk|无影响,那么显然|x1-xa|取最小,即a=1

如果还没理解的我猜你没看到题目的一句话(就像我一开始一样):第二行,N个递增的整数,依次表示N个城市的坐标。

然后我们就可以枚举第二个虫洞的位置了,对于每一个第二个虫洞的位置i,那么数轴上最远距离是

max{x[j-1]-x[1], x[i]-x[j], x[n]-x[i]},其中j是满足x[j]-x[1]<=x[i]-x[j]中最大的j(这是显然的吧,因为如果不成立的话,那么无论是从1走到j还是从i走到j,都不可能比这种情况优)

发现j是单调递增的,那么直接搞就行了,那么就是O(n)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=200005;
int a[N], n, mid, rt, ans;

int main() {
	int cs=getint();
	while(cs--) {
		read(n); ans=~0u>>1;
		for1(i, 1, n) read(a[i]);
		int j=2;
		ans=max(a[2]-a[1], a[n]-a[2]);
		for1(i, 3, n) {
			while(j<i && a[i]-a[j]>a[j]-a[1]) ++j;
			ans=min(max(a[i]-a[j], max(a[j-1]-a[1], a[n]-a[i])), ans);
		}
		printf("%d\n", ans);
	}
	return 0;
}

 

 


 

 

描述

一维的世界就是一个数轴。这个世界的狭小我们几乎无法想象。

在这个数轴上,有N个点。从左到右依次标记为点1到N。第i个点的坐标为Xi。经过漫长时间的物理变化和化学变化,这个一维世界中产生了一个高等智慧文明,而这N个点都成为了这个文明的一座城市。而点1则成为了这个文明的首都。

出于政治上和经济上的需要,首都不能和任何城市相距太远。所以政府决定在某两个城市耗巨资修建虫洞。一个修建了虫洞的城市可以瞬移到另一个修建了虫 洞的城市,从而大大缩短了N个城市相互之间的距离。原先从任意城市i到城市j的路程等于它们的距离|Xi - Xj|,而现在若两个城市附近都有修建了虫洞的城市,则可以先从i移动到附近的虫洞瞬移到城市j附近的虫洞再移动到j。

政府希望在两个合适的城市修建虫洞,使得修建虫洞以后从点1移动到任意城市经过的最短路程的最大值尽量小。请你计算这个路程的最小值是多少。

输入包含多组数据。

格式

输入格式

第一行包括一个正整数T,表示有T组测试数据。接下来依次是T组测试数据。

每组测试数据的第一行包括一个整数N,表示有N个城市。第二行,N个递增的整数,依次表示N个城市的坐标。

输出格式

输出文件包括T行,每行一个整数,依次表示每组测试数据的答案。

样例1

样例输入1[复制]

2
3
0 1 21
5
0 100 101 102 103

样例输出1[复制]

1
2

限制

1s

提示

30%的数据满足:2 <= N <= 200.
60%的数据满足:2 <= N <= 2000.
100%的数据满足:2 <= N <= 200,000, 1 <= T <= 5, |Xi| <= 10^9.

来源

GDKOI 2009

转载于:https://www.cnblogs.com/iwtwiioi/p/4015748.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值