【来源】
一本通题库-1427
LibreOJ-10005
vjudge
注意:一本通题库和LibreOJ题意相同,但输入格式不同。代码以一本通题库为准。
【题目描述】
在黑板上写了 N N N个正整数作成的一个数列,进行如下操作:每一次擦去其中的两个数 a a a和 b b b,然后在数列中加入一个数 a × b + 1 a×b+1 a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的 m a x max max,最小的为 m i n min min,则该数列的极差定义为 M = m a x − m i n M=max−min M=max−min。
【输入格式】
第一行,一个数为 N N N;
第二行, N N N个数。
【输出格式】
输出极差。
【输入样例】
3
1 2 3
【输出样例】
2
【数据范围】
对于全部数据, 0 ≤ n ≤ 50000 0\le n\le 50000 0≤n≤50000,保证所有数据计算均在 32 32 32 位有符号整数范围内。
【解析1】
贪心。
求max:每次选取两个最小的数。
求min:每次选取两个最大的数。
【代码1】
#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define RI register int
#define re(i,a,b) for(RI i=a; i<=b; i++)
#define ms(i,a) memset(a,i,sizeof(a))
#define MAX(a,b) (((a)>(b)) ? (a):(b))
#define MIN(a,b) (((a)<(b)) ? (a):(b))
using namespace std;
typedef long long LL;
int const N=5e4+5;
int n;
int a[N],b[N];
int cmp(int a,int b) {
return a>b;
}
int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
for(int i=1; i<=n; i++) b[i]=a[i];
sort(a+1,a+n+1,cmp);
for(int i=2; i<=n; i++) a[i]=a[i]*a[i-1]+1;
int amin=a[n];
sort(b+1,b+n+1);
for(int i=2; i<=n; i++) {
b[i]=b[i]*b[i-1]+1;
sort(b+1,b+n+1);
}
int amax=b[n];
int ans=amax-amin;
printf("%d\n",ans);
return 0;
}
【解析2】
贪心。
我们可以巧妙利用C++ STL里面的greater和less,以及priority_queue。
对于greater()、less()两个函数:
建堆的时候,默认是大根堆,第三个参数用greater()会变成小根堆。less()反之。
排序的时候,默认是从小到大,但是第三个参数用greater()会变成从大到小。less()反之。
用优先队列代替数组。
两种方法的时间复杂度是相似的。
【代码2】
#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <functional>
#define RI register int
#define re(i,a,b) for(RI i=a; i<=b; i++)
#define ms(i,a) memset(a,i,sizeof(a))
#define MAX(a,b) (((a)>(b)) ? (a):(b))
#define MIN(a,b) (((a)<(b)) ? (a):(b))
using namespace std;
typedef long long LL;
int n;
priority_queue<int,vector<int>,greater<int> > q1;
priority_queue<int,vector<int>,less<int> > q2;
int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
int a;
scanf("%d",&a);
q1.push(a);
q2.push(a);
}
int amax=0;
while(!q1.empty()) {
if(q1.size()==1) {
amax=q1.top();
break;
}
int x=q1.top(); q1.pop();
int y=q1.top(); q1.pop();
q1.push(x*y+1);
}
int amin=0;
while(!q2.empty()) {
if(q2.size()==1) {
amin=q2.top();
break;
}
int x=q2.top(); q2.pop();
int y=q2.top(); q2.pop();
q2.push(x*y+1);
}
int ans=amax-amin;
printf("%d\n",ans);
return 0;
}