【题解】数列极差

题目来源:loj

题目描述

佳佳的老师在黑板上写了一个由n个正整数组成的数列,要求佳佳进行如下操作:每次擦去其中的两个数a和b,然后在数列中加入一个数a*b+1 ,如此下去直至黑板上剩下一个数为止,在所有按这种操作方式最后得到的数中,最大的为max ,最小的为 min, 则该数列的极差定义为M=max-min 。

由于佳佳忙于准备期末考试,现请你帮助他,对于给定的数列,计算出相应的极差

输入格式

第一行为一个正整数n 表示正整数序列的长度;
在接下来的 n行中,每行输入一个正整数。
接下来的一行有一个0,表示数据结束。

输出格式

输出只有一行,为相应的极差 。

样例输入

3
1
2
3
0

样例输出

2

数据范围与提示

对于全部数据,0<=n<=50000,保证所有数据计算均在32位有符号整数范围内。

思路

求最大最小,直觉想到贪心

求max:每次选取数列中最小的两个相乘
求min:每次选取数列中最大的两个相乘

就这个亚子,每次选取数列中最小的两个,我用了priority_queue,至于选最大的两个,很容易可以想到给原来的数列从大到小排序,大的乘大的绝对是比其他小的还要大

code

#include<bits/stdc++.h>
using namespace std;
const int N=50010;
int n,a[N],b;
priority_queue<int,vector<int>,greater<int> >q;//小根堆 

void init()
{
    
    
	scanf("%d",&n);
	for (int i=1;i<=n;i++) 
	{
    
    
		int x;
		scanf("%d",&a[i]);
		q.push(a[i]);
	}
    scanf("%d",&b);
}

int cmp(int x,int y) {
    
     return x>y; }

int work_max()
{
    
    
	int tmp;
	while (!q.empty())
	{
    
    
		tmp=q.top();
		q.pop();
		tmp=tmp*q.top()+1;
		q.pop();
		if (q.empty()) break; 
		q.push(tmp);
	}
	return tmp;
}

int work_min()
{
    
    
	sort(a+1,a+1+n,cmp); //从大到小
	int anss=a[1];
	for (int i=2;i<=n;i++)
		anss=anss*a[i]+1;	
	return anss;
}
int main()
{
    
    
	init();
	int maxx=work_max(); 
    int minn=work_min();
    cout<<maxx-minn<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45485187/article/details/102798470