题目链接:https://vijos.org/d/ybttg/p/5c24b688f41362c9e1912651

时间限制:1000 ms 内存限制:512 MiB

题目描述

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

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

输入格式

第一行为一个正整数 n n n表示正整数序列的长度;

在接下来的 n n n行中,每行输入一个正整数。

接下来的一行有一个 0 0 0,表示数据结束。

输出格式

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

样例输入


3
1
2
3
0


样例输出


2


限制与提示


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


解题思路

题意: 给你一个集合,每次从中删除两个数 a , b a, b a,b,并添加 a × b + 1 a \times b+1 a×b+1,直到剩最后一个数为止,在所有按这种操作方式最后得到的数中,最大与最小的差值。

思路: 显然可使用贪心策略。在求最大值的时候每次要选择较小的数操作,反过来求最小值时每次要选择较大的数操作。

Accepted Code:

/* 
* @Author: lzyws739307453
* @Language: C++
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int main() {
int n;
priority_queue <int, vector <int>, less <int> > Ql;
priority_queue <int, vector <int>, greater <int> > Qg;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
Ql.push(x);
Qg.push(x);
}
while (Ql.size() > 1) {
int x = Ql.top();
Ql.pop();
int y = Ql.top();
Ql.pop();
Ql.push(x * y + 1);
}
while (Qg.size() > 1) {
int x = Qg.top();
Qg.pop();
int y = Qg.top();
Qg.pop();
Qg.push(x * y + 1);
}
printf("%d\n", Qg.top() - Ql.top());
return 0;
}