• qmh的测试1


    题目:传送门

     

    首先输入一个n,之后输入n个数a(1<=a<=1e7),对这n个数排序后,你需要找到所有的它们连续的长度。把这些连续的长度排序后输出

    输入

     

    输入:

    8

    1 5 2 7 4 5 7 1

    输出

     

    输出:

    1 2 2

    样例解析:

    将上面数排序得:

    1 1 2 4 5 5 7 7

    去重后 :

    1 2 4 5 7

    连续长度:

    2 2 1

    因为1 2 4之间少一个3去连接,所以1 2和4之间要断开。又因为4 5和7之间少一个6来连接,所以5和7直之间要断开

    结果排序后:

    1 2 2

    题解:

    因为n最大是是1e7,而且程序必须在1s内得到答案。所以我们这里肯定要使用O(n)复杂度的木桶排序

    对于:1 5 2 7 4 5 7 1 这一组数据

    如果使用木桶排序的话数组至少要开到v[9],因为用木桶排序用的数据本身当v数组的下标

        v数组: 0 1 2 3 4 5 6 7 8 9     //数组下标

    处理一下v数组: 0 1 1 0 1 1 0 1 0 0     //这里的1代表这个下标在输入的数据中出现过,0代表没有出现过。比如v[2]=1,就表示2这个数在我们输入的数据中

    代码:

    #include <stdio.h>
    #include<string.h>
    #include <iostream>
    #define INF 0x3f3f3f3f
    using namespace std;
    const int maxn=1e7+5;
    int v[maxn],w[maxn],p[maxn];
    int main()
    {
            int n,a,maxx=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&a);
            v[a]=1;
            maxx=max(maxx,a);
        }
    }

    这样处理过之后我们发现完成了去重和排序

    for(int i=1;i<=maxx;++i)
        {
            if(v[i]>0)
            {
                printf("%d ",i);
            }
        }
        printf("
    ");   

    你可以用这个代码把v数组打印出来结果会是1 2 4 5 7

    之后我们就要求它的连续长度,这个时候就新定义一个数组w和p

    int ans=0,i;
        for(i=1;i<=maxx;++i){
            if(v[i]){
                w[i]=w[i-1]+1;
            }
            else {
                p[w[i-1]]++;
                ans=max(ans,w[i-1]);  //我们把 
            }
        }
     下标  :0 1 2 3 4 5 6 7 8 9
    v中的值:0 1 1 0 1 1 0 1 0 0 
    w初始值:0 0 0 0 0 0 0 0 0 0
    处理后w:0 1 2 0 1 2 0 1 0 0
    把w[1,7]这个下标内的,所有0之前的值都存起来,因为它就是那个连续长度
    2 2 1  这个1不在0之前但是它也是连续长度,我们也要把它取出来
    第一个2是{12}这两个数的两个数的连续长度。
    第二个2是{45}这两个数的连续长度
    第三个数1是{7}这1个数的连续长度 

    这样的话,我们就会得到2 2 1这个结果,但是我们还要对它排序后再输出。这里又要用到木桶排序

    但是我已经把它们放在木桶p里面了

    int ans=0,i;
        for(i=1;i<=maxx;++i){
            if(v[i]){
                w[i]=w[i-1]+1;
            }
            else {  //else就是出现了断点0 
                p[w[i-1]]++;  //把这个数用木桶存起来 
                ans=max(ans,w[i-1]);  //找到这个木桶的右端点 ,以便我们下一步输出的时候去枚举 
            }  //因为木桶排序是把这个数当作下标,所以要找右端点只需要看你需要用到的最大下标是多少 
        }

    下标:      0 1 2 3 4

    p初始值:0 0 0 0 0 

    处理后p:0 1 2 0 0 

    之后就打印出就可以了,注意格式:

    p[w[i-1]]++;  
    ans=max(ans,w[i-1]);  //不加这两行代码的话,这个样例中的1,就会没有放到木桶p中
        
        for(int i=1;i<=ans;++i){
            while(p[i])
            {
                if(i==ans && p[i]==1)
                    printf("%d
    ",i);
                else 
                    printf("%d ",i);
                p[i]--;
            }
        }
     

    总代码:用c++格式提交

     1 #include <stdio.h>
     2 #include<string.h>
     3 #include <iostream>
     4 #define INF 0x3f3f3f3f
     5 using namespace std;
     6 const int maxn=1e7+5;
     7 int v[maxn],w[maxn],p[maxn];
     8 int main(){
     9     //while(1){
    10     //    memset(w,0,sizeof(w));
    11     //    memset(v,0,sizeof(v));
    12     //    memset(p,0,sizeof(p));
    13     int n,a,maxx=0;
    14     scanf("%d",&n);
    15     for(int i=1;i<=n;++i)
    16     {
    17         scanf("%d",&a);
    18         v[a]=1;
    19         maxx=max(maxx,a);
    20     }
    21     int ans=0,i;
    22     for(i=1;i<=maxx;++i){
    23         if(v[i]){
    24             w[i]=w[i-1]+1;
    25         }
    26         else {
    27             //printf("%d**
    ",w[i-1]);
    28             p[w[i-1]]++;
    29             ans=max(ans,w[i-1]);
    30         }
    31     }
    32     p[w[i-1]]++;
    33     ans=max(ans,w[i-1]);
    34     
    35     for(int i=1;i<=ans;++i){
    36         while(p[i])
    37         {
    38             if(i==ans && p[i]==1)
    39                 printf("%d
    ",i);
    40             else 
    41                 printf("%d ",i);
    42             p[i]--;
    43         }
    44     }
    45 //    }
    46     
    47     return 0;
    48 } 
    View Code

    c格式代码:

     1 #include <stdio.h>
     2 #include<string.h>
     3 #define maxn 10000000+5
     4 int v[maxn],w[maxn],p[maxn];
     5 int max(int x,int y){
     6     if(x>y) return x;
     7     else return y;
     8 }
     9 int main(){
    10     int n,a,maxx=0;
    11     scanf("%d",&n);
    12     for(int i=1;i<=n;++i)
    13     {
    14         scanf("%d",&a);
    15         v[a]=1;
    16         maxx=max(maxx,a);
    17     }
    18     int ans=0,i;
    19     for(i=1;i<=maxx;++i){
    20         if(v[i]){
    21             w[i]=w[i-1]+1;
    22         }
    23         else {
    24             p[w[i-1]]++;
    25             ans=max(ans,w[i-1]);
    26         }
    27     }
    28     p[w[i-1]]++;
    29     ans=max(ans,w[i-1]);
    30     
    31     for(int i=1;i<=ans;++i){
    32         while(p[i])
    33         {
    34             if(i==ans && p[i]==1)
    35                 printf("%d
    ",i);
    36             else 
    37                 printf("%d ",i);
    38             p[i]--;
    39         }
    40     }
    41     return 0;
    42 } 
    View Code

    生成数据的代码:

     1 #include <bits/stdc++.h>
     2 #include<fstream>
     3 #define INF 0x3f3f3f3f
     4 using namespace std;
     5 const int maxx=1e7;
     6 const int minn=1;
     7 const int N=4; 
     8 int w[maxx+5],p[maxx+5],v[maxx+5];
     9 string getname(int i, string a)
    10 {
    11     stringstream ss;
    12     ss << i << a;
    13     return ss.str();
    14 }
    15 int int_rand(int min,int max)
    16 {
    17     return int(min+rand()%(max-min));
    18 }
    19 int main(){
    20     srand((unsigned)time(NULL)); //随机种子
    21     //for(int i=1;i<=N;++i){
    22         string name1, name2;
    23         //name1 = getname(i, ".in");
    24         //name2 = getname(i, ".out");
    25         ofstream fp2("1.out", ios::out);
    26         ofstream fp1("1.in", ios::out);
    27         //fp2.open(name2, ios::out);
    28         
    29     int n=int_rand(minn,maxx),a,maxn=0;
    30     //printf("%d
    ",n);
    31     fp1<<n;
    32     fp1<<("
    ");
    33     for(int i=1;i<=n;++i){
    34         a=int_rand(minn,maxx);
    35         //printf("%d
    ",a);
    36         v[a]=1;
    37         maxn=max(maxn,a);
    38         if(i!=n) {
    39             fp1<<a<<" ";
    40         }
    41         else {
    42             fp1<<a<<"
    ";
    43         }
    44     }
    45     
    46     //memset(w,0,sizeof(w));
    47     //memset(v,0,sizeof(v));
    48     //memset(p,0,sizeof(p));
    49     //int a;
    50     //for(int i=1;i<=n;++i)
    51     //{
    52     //    scanf("%d",&a);
    53     //    v[a]=1;
    54     //    maxx=max(maxx,a);
    55     //}
    56     int ans=0,i;
    57     for(i=1;i<=maxn;++i){
    58         if(v[i]){
    59             w[i]=w[i-1]+1;
    60         }
    61         else {
    62             p[w[i-1]]++;
    63             ans=max(ans,w[i-1]);
    64         }
    65     }
    66     p[w[i-1]]++;
    67     ans=max(ans,w[i-1]);
    68     
    69     for(int i=1;i<=ans;++i){
    70         while(p[i])
    71         {
    72             if(i==ans && p[i]==1)
    73                 fp2<<i<<"
    ";//,printf("%d
    ",i);
    74             else 
    75                 fp2<<i<<" ";//,printf("%d ",i);
    76             p[i]--;
    77         }
    78     }
    79 
    80      
    81         fp1.close();
    82         //fp2.close();
    83 //    }
    84 } 
    View Code
  • 相关阅读:
    python之九九乘法表
    python选择排序有序区域和无序区域
    mysql学习笔记(一)
    cuda toolkit安装
    vs 无法打开输入文件“kernel32.lib”
    vs libtorch 无法定位程序输入点…于动态链接库…exe
    libtorch 部署 windows10
    openvino记录
    AcWing 803.区间合并
    AcWing 802.区间和
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11628424.html
Copyright © 2020-2023  润新知