首页 > 其他 > 详细

qmh的测试1

时间:2019-10-06 21:38:06      阅读:83      评论:0      收藏:0      [点我收藏+]

题目:传送门

 

 

首先输入一个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("\n");   

你可以用这个代码把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\n",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**\n",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\n",i);
40             else 
41                 printf("%d ",i);
42             p[i]--;
43         }
44     }
45 //    }
46     
47     return 0;
48 } 
View Code

 

qmh的测试1

原文:https://www.cnblogs.com/kongbursi-2292702937/p/11628424.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!