NanoApe Loves Sequence
2016-08-08 16:24
106 查看
退役狗 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;
}//本题说为了防止产生误差其实是方便计算,其实这题含义是把每个值删一次之后这个数列相邻两数差的绝对值最大之和
//这题要考虑许多情况,包括开头和结尾,以及中间的可能出现最大和第二大相邻的情况,所以要引入第三大的值
在数学课上,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;
}//本题说为了防止产生误差其实是方便计算,其实这题含义是把每个值删一次之后这个数列相邻两数差的绝对值最大之和
//这题要考虑许多情况,包括开头和结尾,以及中间的可能出现最大和第二大相邻的情况,所以要引入第三大的值
相关文章推荐
- HDU 5806 - NanoApe Loves Sequence Ⅱ (BestCoder Round #86)
- hdu:5805:前缀和后缀NanoApe Loves Sequence
- HDU-5805-NanoApe Loves Sequence(水题)
- NanoApe Loves Sequence(求最大值的期望)
- HDU 5805 NanoApe Loves Sequence(ST 表 or 预处理)
- 【HDU5805 BestCoder Round 86B】【前后缀和】NanoApe Loves Sequence 删除一数后数列max(相邻数绝对值)
- HDU 5806 NanoApe Loves Sequence Ⅱ
- BC#86.1002(HDOJ5805)NanoApe Loves Sequence
- HDU-5806-NanoApe Loves Sequence Ⅱ(水题)
- HDU 5805 NanoApe Loves Sequence
- BC#86 1003NanoApe Loves Sequence Ⅱ[two-pointer]
- hdu NanoApe Loves Sequence
- HDU 5806 NanoApe Loves Sequence Ⅱ(尺取法)
- hdu5806:NanoApe Loves Sequence Ⅱ
- HDU 5805 NanoApe Loves Sequence (思维题) BestCoder Round #86 1002
- BC#86.1003(HDOJ5806)NanoApe Loves Sequence Ⅱ
- hdu NanoApe Loves Sequence Ⅱ
- Hdu 5805 NanoApe Loves Sequence【思维题】
- HDU 5806 NanoApe Loves Sequence Ⅱ two pointers
- BestCoder Round #86 1002 &HDU 5805 ——NanoApe Loves Sequence