Distance

题目链接:https://www.nowcoder.com/acm/contest/16/B

FST作为小朋友,经常会遇到和距离有关的问题,但是他已经厌倦了曼哈顿距离和欧几里德距离,所以FST就定义了一种FST距离。
这种距离并不用于空间或平面中,而运用于FST发明的一些神奇的算法中(唔... ...)。
设i号元素的特征值为A i,则i和j的FST距离是 |i 2 - j 2|+|A i 2 - A j 2|。
为了实现某新的数据结构,FST想在一大堆元素中找出距离最大的一对元素,他不关心是哪一对元素,只想求出最大距离。

输入描述:

第一行,一个正整数n,为元素个数。
第二行,n个正整数Ai为这n个元素的特征值。

输出描述:

一行,一个正整数表示最大距离。long long请用lld
示例1

输入

2
4 3

输出

10

备注:

n≤105,Ai≤109


题目分析:刚看到这个题的时候就看出来是个贪心,但是这个式子不太好,开平方、开根号、同乘两部分相减......各种乱七八糟的都试了,最后想到既然带着绝对值号不好求,那么干脆就把绝对值号去掉,去绝对值号的话可以分成4种情况。



分别按这四种情况排序然后找出这四种情况里的最大值。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
	ll I,A;
};
node a[100010];

int cmp1(node x,node y){
	return x.I*x.I+x.A*x.A>y.I*y.I+y.A*y.A;
}
int cmp2(node x,node y){
	return x.I*x.I+y.A*y.A>y.I*y.I+x.A*x.A;
}
int cmp3(node x,node y){
	return y.I*y.I+x.A*x.A>x.I*x.I+y.A*y.A;
}
int cmp4(node x,node y){
	return y.I*y.I+y.A*y.A>x.I*x.I+x.A*x.A;
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i].A);
		a[i].I=i;
	}
	ll maxx=0;
	sort(a+1,a+n+1,cmp1);
	if(abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A)>maxx)
		maxx=abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A);
	sort(a+1,a+n+1,cmp2);
	if(abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A)>maxx)
		maxx=abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A);
	sort(a+1,a+n+1,cmp3);
	if(abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A)>maxx)
		maxx=abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A);
	sort(a+1,a+n+1,cmp4);
	if(abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A)>maxx)
		maxx=abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A);
	printf("%lld\n",maxx);
	return 0;
}


其实这个的第1种和第4,第2种和第3种算是同种情况,理论按照1和2排两次序就可以。(赛后又交了一次,可以过!!!)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
	ll I,A;
};
node a[100010];

int cmp1(node x,node y){
	return x.I*x.I+x.A*x.A>y.I*y.I+y.A*y.A;
}
int cmp2(node x,node y){
	return x.I*x.I+y.A*y.A>y.I*y.I+x.A*x.A;
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i].A);
		a[i].I=i;
	}
	ll maxx=0;
	sort(a+1,a+n+1,cmp1);
	if(abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A)>maxx)
		maxx=abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A);
	sort(a+1,a+n+1,cmp2);
	if(abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A)>maxx)
		maxx=abs(a[1].I*a[1].I-a[n].I*a[n].I)+abs(a[1].A*a[1].A-a[n].A*a[n].A);
	printf("%lld\n",maxx);
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值