[HDU5805]-NanoApe Loves Sequence

NanoApe Loves Sequence

 
 Accepts: 531
 
 Submissions: 2481
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 262144/131072 K (Java/Others)
Problem Description

NanoApe, the Retired Dog, has returned back to prepare for the National Higher Education Entrance Examination!

In math class, NanoApe picked up sequences once again. He wrote down a sequence with nn numbers on the paper and then randomly deleted a number in the sequence. After that, he calculated the maximum absolute value of the difference of each two adjacent remained numbers, denoted as FF.

Now he wants to know the expected value of FF, if he deleted each number with equal probability.

Input

The first line of the input contains an integer TT, denoting the number of test cases.

In each test case, the first line of the input contains an integer nn, denoting the length of the original sequence.

The second line of the input contains nn integers A_1, A_2, ..., A_nA1,A2,...,An, denoting the elements of the sequence.

1 \le T \le 10,~3 \le n \le 100000,~1 \le A_i \le 10^91T10, 3n100000, 1Ai109

Output

For each test case, print a line with one integer, denoting the answer.

In order to prevent using float number, you should print the answer multiplied by nn.

Sample Input
1
4
1 2 3 4
Sample Output
6
题目描述:
    每次删除一个数,然后算的相邻点最大值(取绝对值),全部加起来,(题目愿意是每种取法概率值为1/n,让你求最大值的期望,最后又让你确保精度结果*n,所以就不同考虑了)。
解题思路:
    先把每个相邻点的绝对值存到add数组中,按降序排序,其实我们只用看去掉的这个数他和他前面的数差绝对值(有人也叫做前缀),他后面的数差绝对值(有人也叫后缀),前缀和后缀差绝对值(我们这取做前后差吧)和当前最大数的关系,我说的可能有点含糊,用代码描述吧:
    我们每删除一个元素(第一个和最后一个例外),先判断他前缀和后缀是否有一个是最大值,如果是的话那么第二大数(add[1])就成了第一个大数,然后取add[1]与前后差中最大的一个,但是如果他的前缀和后缀分别是第一大数和第二大数,如果是的话那么第三大数(add[2])就成了第一个大数,然后取add[2]与前后差中最大的一个,如果前后缀都没有一个数等于第一大数,就拿add[0]与前后差作比较,取最大值。
    这里我入了一个坑,add数组我没初始化,我忘了只有3个数的情况了,wa了好几次,还有一个温馨提示:记得全部都要用绝对值哦!
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 100009;
typedef __int64 LL;
int nums[maxn];
int add[maxn];
int max(int a,int b)
{
	return a > b? a : b;
}
bool cmp(int a,int b)
{
	return a>b;
}
int main()
{
	int t;
	ios::sync_with_stdio(false);
	scanf("%d",&t);
	while(t --)
	{
		int n;
		int cnt=0;
		scanf("%d",&n);
		memset(add,0,maxn);
		for(int i = 0;i < n;++ i)
		{
			scanf("%d",nums+i);
			if(i>0)
				add[cnt++]=abs(nums[i]-nums[i-1]);
		}
		LL ans = 0;
		sort(add,add+cnt,cmp);
		if(abs(nums[1]-nums[0])==add[0])//去掉第一个数
			ans += add[1];
		else
			ans += add[0];
		if(abs(nums[n-1]-nums[n-2])==add[0])//去掉最后一个数
			ans += add[1];
		else
			ans += add[0];
		for(int i = 1;i < n-1;++ i)
		{
			if((abs(nums[i]-nums[i-1])==add[0])||abs(nums[i+1]-nums[i])==add[0])
			{
				if(abs(nums[i]-nums[i-1])==add[1]||abs(nums[i+1]-nums[i])==add[1])
				{
					ans += max(add[2],abs(nums[i+1]-nums[i-1]));
				}
				else
					ans += max(add[1],abs(nums[i+1]-nums[i-1]));
			}
			else
				ans += max(add[0],abs(nums[i+1]-nums[i-1]));
		}
		printf("%I64d\n",ans);
	}
	return 0;
}


  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值