• P5682 [CSPJX2019]次大值【民间数据】


    题目描述

    Alice 有 nnn 个正整数,数字从 1∼n1 sim n1n 编号,分别为 a1,a2,…,ana_1,a_2, dots , a_na1,a2,,an
    Bob 刚学习取模运算,于是便拿这 nnn 个数进行练习,他写下了所有

    ai mod aj(1≤i,j≤n∧i≠j)a_i mod a_j (1 le i,j le n wedge i eq j) aimodaj(1i,jni=j)

    的值,其中  mod modmod 表示取模运算。

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

    输入格式

    第一行一个正整数 nnn,表示数字个数。
    第二行 nnn 个正整数表示 aia_iai

    输出格式

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

    输入输出样例

    输入 #1
    4
    4 5 5 6
    输出 #1
    4
    输入 #2
    4
    1 1 1 1
    输出 #2
    -1
    输入 #3
    7
    12 3 8 5 7 20 15
    输出 #3
    12

    说明/提示

    【数据范围】
    对于 40%40\%40% 的数据,1≤n,ai≤1001le n,a_i le 1001n,ai100;
    对于 70%70\%70% 的数据,1≤n≤30001le n le 30001n3000,1≤ai≤1051le a_i le 10^51ai105;
    对于 100%100\%100% 的数据,3≤n≤2×1053 le n le 2 imes 10^53n2×105,1≤ai≤1091le a_i le 10^91ai109。

    【样例 111 解释】
    所有取模的结果为 {4,4,4,1,0,5,1,0,5,2,1,1}{4,4,4,1,0,5,1,0,5,2,1,1}{4,4,4,1,0,5,1,0,5,2,1,1}。
    去重后有:{0,1,2,4,5}{0,1,2,4,5 }{0,1,2,4,5},结果为 444。

    根据题意要求,最后我们是要进行去重操作的,所以不管在哪里去重都是可以的,所以我们先对于读入数据进行去重,然后从小到大排序,因为我们知道,每个元素都需要和除他之外的所有元素进行比较,所以我们这样的操作其实对于我们最后的操作是没有影响的;

    然后,转折点来了qwq

    到这一步其实正解是一种非常简单的做法,但是由于本人过于蒟蒻,所以我的方法是两层循环,为了降低复杂度,我们发现,从小到大对元素进行排序之后,如果a%b中b的值大于a,那么就是说之后所有元素的值都大于a,所以a%他们其实结果就是a,依据这样的方法,我开心的把代码敲了出来,开心的交了上去,然后开心的发现自己最后三个点T了qwq

    也就是说上面这种方法虽然在一定程度上降低了时间复杂度,但是对于某些特殊数据,它的复杂度还是太高的,所以我们来想另外的方法

    其实在第一种方法中我们就可以发现,有由于所有元素都是从小到大排序的,所以除了最后一个元素之外,每一个元素取余的最大值就是他自己,所以严格次大值其实就是倒数第三个数的值,but,题目中还有一个坑点在于他没有规定i j的比较顺序,也就是说,可以用大数%小数,这样的话得到的数一定比大数小,按照常理来说,这种情况可以很容易被排除,但是不要忘了我们还有最后一个个元素呢!我们不知道最后一个元素%倒数第二个元素的值与倒数第三个元素的值到底谁大谁小,所以应该再取一次MAX才对

    70分代码(本人第一遍写的qwq)

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    int vis[5020000];
    int num=0;
    int ans[5020000];
    int a[5020000];
    
    int main() {
        cin>>n;
        for(int i=1; i<=n; i++) {
            int x;
            cin>>x;
            if(!vis[x]) {
                num++;
                vis[x]=1;
                a[num]=x;
            }
        }
        sort(a+1,a+num+1);// small
    
        int c=0;
        for(int i=1; i<=num; i++) {
            bool flag=0;
            for(int j=1; j<=num; j++) {
                if(a[i]==a[j]) continue;
                if(a[i]>a[j]&&flag==1) break;
                c++;
                ans[c]=a[i]%a[j];
            }
        }
        num=0;
        int b[502000];
        memset(vis,0,sizeof(vis));
        sort(ans+1,ans+1+c);
        for(int i=1; i<=c; i++) {
            int x=ans[i];
            if(!vis[ans[i]]) {
                num++;
                vis[ans[i]]=1;
                b[num]=ans[i];
            }
        }
        sort(b+1,b+1+num);
        if(num==0) cout<<-1<<endl;
        else cout<<b[num-1]<<endl;
        return 0;
    }

    正解(AC代码):

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    int vis[5020000];
    int num=0;
    int ans[5020000];
    int a[5020000];
    int b[5020000];
    int main() {
        cin>>n;
        for(int i=1; i<=n; i++) {
                int x;
                cin>>x;
                if(!vis[x]) {
                    num++;
                    vis[x]=1;
                    a[num]=x;
                }
            }
            sort(a+1,a+num+1);// small
            if(num>=3) cout<<max(a[num-2],a[num]%a[num-1])<<endl;
            else cout<<-1<<endl;
            return 0;
    }

    完结撒花✿✿ヽ(°▽°)ノ✿

    根据题意要求,最后我们是要进行去重操作的,所以不管在哪里去重都是可以的,所以我们先对于读入数据进行去重,然后从小到大排序,因为我们知道,每个元素都需要和除他之外的所有元素进行比较,所以我们这样的操作其实对于

  • 相关阅读:
    Python MySQL(SQL语句的补充3)
    Python MySQL(pymysql的使用day1)
    Python MySQL(SQL语句的补充2)
    Python MySQL(对外键使用方法的补充)
    Python MySQL(学习SQL语句)
    Python MySQL数据库的基本使用
    关于http响应内容压缩的一点小积累。
    同一账号,后一用户登录,前一个用户则被踢掉
    对序列化的学习。
    MySQL 函数积累
  • 原文地址:https://www.cnblogs.com/yxr001002/p/14053906.html
Copyright © 2020-2023  润新知