P5682 [CSP-J 2019] 次大值

题目描述

传送门

Alice 有 \(n\) 个正整数,数字从 \(1 \sim n\) 编号,分别为 \(a_1,a_2, \dots , a_n\)
Bob 刚学习取模运算,于是便拿这 \(n\) 个数进行练习,他写下了所有

\[a_i \bmod a_j (1 \le i,j \le n \wedge i \neq j) \]

的值,其中 \(\bmod\) 表示取模运算。

Alice 想知道所有的结果中,严格次大值是多少。将取模后得到的所有值进行去重,即相同的结果数值只保留一个,剩余数中第二大的值就称为严格次大值。

输入格式

第一行一个正整数 \(n\),表示数字个数。
第二行 \(n\) 个正整数表示 \(a_i\)

输出格式

仅一行一个整数表示答案。
若取模结果去重后剩余数字不足两个,则输出 \(-1\)

样例

样例输入

4
4 5 5 6

样例输出

4

思路

首先它要求严格次大值 所以有两个相同的数没有意义...先排序+去重
假设原序列去重后剩下的序列为\(a_1,a_2, \dots , a_n\)

由于 \(a \bmod b <a\) 所以最大值一定是 a[n-1] mod a[n].
简单证明:

  • 1.对于 \(a_1\) 到 a[n-2] 使其取模比它们大的数 就是本身 一定比 a[n-1]小。
  • 2.如果一个数模比它小的数 被模的数不可能是 \(a_n\) 那么最后值一定小于 a[n-1].

代码实现

#include<bits/stdc++.h>
using namespace std;
int n;
int a[200005];
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
    
	sort(a+1,a+n+1);
	n=unique(a+1,a+n+1)-a-1;
	a[0]=0;
    
	if(n<=1){
		cout<<-1<<endl;
	}
	else cout<<max(a[n-2],a[n]%a[n-1]);
	return 0;
}

posted @ 2023-10-02 15:02  j1hx  阅读(159)  评论(0)    收藏  举报