NanoApe Loves Sequence

探讨了在删除数列中任意一个数后,其余数相邻差值的绝对值最大值的期望计算方法。该文提供了一种算法实现,考虑各种特殊情况以确保计算的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

退役狗 NanoApe 滚回去学文化课啦!
在数学课上,NanoApe 心痒痒又玩起了数列。他在纸上随便写了一个长度为 n 的数列,他又根据心情随便删了一个数,这样他得到了一个新的数列,然后他计算出了所有相邻两数的差的绝对值的最大值。
他当然知道这个最大值会随着他删了的数改变而改变,所以他想知道假如全部数被删除的概率是相等的话,差的绝对值的最大值的期望是多少。


第一行为一个正整数 TT,表示数据组数。
每组数据的第一行为一个整数 n。
第二行为 n 个整数 Ai,表示这个数列。
1<=T<=10,3<=n<=100000,1<=Ai<=10^9


对于每组数据输出一行一个数表示答案。
为防止精度误差,你需要输出答案乘上 nn 后的值。




输入
1
4
1 2 3 4


输出

6

#include<stdio.h>
#include<stdlib.h>
int st[100005];//用数组存下每两个的绝对值 
int main(void)
{
	int T,i,j;
	scanf("%d",&T);
	while(T--)
	{
		int a,b,c,n,max1,max2,max3=0,tmax1,tmax2,first=1;
		long long s=0;//求期望值 
		scanf("%d",&n);
		scanf("%d%d%d",&a,&b,&c);
		if(abs(a-b)>=abs(b-c))//将第一大第的二大的依次存入max1、max2 
		{
			max1=abs(a-b);
			max2=abs(b-c);
			tmax1=0;//记录两值的位置 
			tmax2=1;
			st[0]=a-b;
			st[1]=b-c;
		}
		else
		{
			max1=abs(b-c);
			max2=abs(a-b);
			tmax1=1;
			tmax2=0;
			st[0]=a-b;
			st[1]=b-c;	
		}
		a=c;
		c=2;
		for(i=4;i<=n;i++)
		{
			scanf("%d",&b);
			if(first)
			{
				if(abs(a-b)>max1)//判断新增加的大小,始终保证max1是最大,max2第二大,!!!注意记位置的也要变 
				{//并存入第三大的变量 
					max3=max2;
					max2=max1;
				max1=abs(a-b);
					tmax2=tmax1;
					tmax1=2;
				}
				else if(abs(a-b)>max2)
				{
					max3=max2;
					max2=abs(a-b);
					tmax2=2;
				}
				else
					max3=abs(a-b);
				first=0;
			}
			else
			{
				if(abs(a-b)>max1)
				{
					max3=max2;
					max2=max1;
					max1=abs(a-b);
					tmax2=tmax1;
					tmax1=c;
				}
				else if(abs(a-b)>max2)
				{
					max3=max2;
					max2=abs(a-b);
					tmax2=c;
				}
				else if(abs(a-b)>max3)
					max3=abs(a-b);
			}
			st[c++]=a-b;//将每个差的值保存起来,不是绝对值 
			a=b;	
		}
		for(i=1;i<=n;i++)
		{
			if(i==1)//如果去掉第一个 
			{
				if(tmax1==0)//如果第一个是第一大的,那么取第二大的。否则取第一大的 
					s=s+max2;
				else
					s=s+max1;
			}
			else if(i==n)//如果去掉的是最后一个 
			{
				if(tmax1==n-2)//如果第一个是第一大的,那么取第二大的。否则取第一大的 
					s=s+max2;
				else
					s=s+max1;	
			}
			else
			{
				if(i==tmax1+1)//如果去掉的是第一大前部分的 
				{
					if(tmax2==tmax1-1)//如果第一大前是第二大的
					{
						if(abs(st[i-2]+st[i-1])>=max3)//如果两个差的和的绝对值大于第三大的,取绝对值,否则取第三大的 
							s=s+abs(st[i-2]+st[i-1]);
						else
							s=s+max3;		
					}
					else
					{
						if(abs(st[i-2]+st[i-1])>=max2)
							s=s+abs(st[i-2]+st[i-1]);
						else
							s=s+max2;		
					}
				}
				else if(i==tmax1+2)//如果去掉的是第一大后部分的 
				{
					if(tmax2==tmax1+1)//如果第一大后是第二大的 
					{
						if(abs(st[i-2]+st[i-1])>=max3)
							s=s+abs(st[i-2]+st[i-1]);
						else
							s=s+max3;
					}
					else
					{
						if(abs(st[i-2]+st[i-1])>=max2)
							s=s+abs(st[i-2]+st[i-1]);
						else
							s=s+max2;						
					}
				}
				else//如果两个差和的绝对值大于最大值,取这个,否则取绝对值 
				{
					if(abs(st[i-2]+st[i-1])>=max1)
						s=s+abs(st[i-2]+st[i-1]);
					else
						s=s+max1;
				}
			}
		}
		printf("%lld\n",s);
	}
	return 0;
}//本题说为了防止产生误差其实是方便计算,其实这题含义是把每个值删一次之后这个数列相邻两数差的绝对值最大之和
 //这题要考虑许多情况,包括开头和结尾,以及中间的可能出现最大和第二大相邻的情况,所以要引入第三大的值 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值