题目描述
“我就说你在忽悠我吧,我刚才问了昆士兰大学的好多魔法师,他们根本就没有一个人想过做什么时间旅行的实验,但搞笑的是,他们居然对你的理论很感兴趣,想找个时间和你做进一步的讨论。哎,我还以为他们和我一样聪明呢,想不到这么容易上当受骗。”小墨老师摆出一幅你骗不了我的表情。
“唉,你太自以为是了,这样吧,你先把这道数列极差问题发给他们,如果他们能有所领悟,那我会找时间和他们讨论一下时间旅行的可行性的。”李旭琳边说边在黑板上写了N个正整数组成的一个数列,并进行如下操作:每次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的为max,最小的为min,则该数列的极差定义为M=max-min。
现在请你编程,对于给定的数列,计算极差。
“唉,你太自以为是了,这样吧,你先把这道数列极差问题发给他们,如果他们能有所领悟,那我会找时间和他们讨论一下时间旅行的可行性的。”李旭琳边说边在黑板上写了N个正整数组成的一个数列,并进行如下操作:每次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的为max,最小的为min,则该数列的极差定义为M=max-min。
现在请你编程,对于给定的数列,计算极差。
输入
输入包含多个测试集。每个测试集的第一个数N表示 正整数序列长度(0≤N≤50000),随后是N个正整数。N为0表示输入结束。
输出
每个结果一行。
样例输入
3
1 2 3
0
样例输出
2
1:(1*2+1)*3+1=10
2:(1*3+1)*2+1=9
3:(2*3+1)*1+1=8
从中我们容易发现这样的顺序,如果要求最大值的话,那么每次先用最小的连个数相乘的结果+1,相反,如果要求最小值的话,每次先用最大的两个数相乘的结果+1.这样我们就可以写算法啦
#include<iostream>
#include<algorithm>
using namespace std;
//定义两个数组用于求最大和最小值得时候使用
int s[50001];
int j[50001];
int cmp(int a,int b){
return a>b;
}
int main(){
int n;
while(cin>>n&&n){
for(int i=0;i<n;i++){
cin>>s[i];
j[i]=s[i];
}
//先升序排列
sort(s,s+n);
for(int i=1;i<n;i++){
s[i]=s[i]*s[i-1]+1;//从小到大排完序之后,先从前边最小的两个数相乘然后存放到数组里
sort(s+i,s+n);/*算法的核心部分,由于每次从最小的两个数相乘后的数值
放到原来的数组中有可能会破坏数组从小到大的顺序,所以再用一个sort排序,使新的数组变得有序,
依次循环下去,就会得到最大值。*/
}
int max=s[n-1];
//降序排列并求最小值
sort(j,j+n,cmp);
for(int i=1;i<n;i++){
j[i]=j[i-1]*j[i]+1;/*而求最小值的时候就不用sort每次都排序啦,因为前边两个最大的数乘起来
的数不可能会比后边小的数还要小,所以求最小值得时候会比上边要简单一些*/
}
int min=j[n-1];
cout<<max-min<<endl;
}
return 0;
}