数字在排序数组中出现的次数——离线查询

http://ac.jobdu.com/problem.php?cid=1039&pid=20

统计一个数字在排序数组中出现的次数。

因为观察的题目时间复杂度为O(n),所以先到一次遍历

动态查找显然不现实,所以用离线查找,将需要查找的先进行排序,在一次遍历

提供两组数据以供测试

10
1 2 2 2 3 3 3 3 4 5
6
-1 -9 1 3 4 2

10
1 2 2 2 3 3 3 3 4 5
10
1 2 2 2 3 3 3 3 4 5

View Code
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;

template <class T>  
inline bool scan_d(T &ret) {  
   char c; int sgn;  
   if(c=getchar(),c==EOF) return 0; //EOF  
   while(c!='-'&&(c<'0'||c>'9')) c=getchar();  
   sgn=(c=='-')?-1:1;  
   ret=(c=='-')?0:(c-'0');  
   while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');  
   ret*=sgn;  
   return 1;  
} 

int ss[1000099];
struct data
{
    int no;
    int temp;
    int v;
}que[1099];

int cmp1(data a,data b)
{
    return a.temp<b.temp;
}

int cmp2(data a,data b)
{
    return a.no<b.no;
}

int main()
{
    int n,m,i;
    while(scanf("%d",&n)!=EOF){
        for(i=1;i<=n;i++){
            scan_d(ss[i]);
        }ss[n+1]=-999999999;

        scanf("%d",&m);
        for(i=1;i<=m;i++){
            que[i].no=i;
            que[i].v=0;
            scan_d(que[i].temp);
        }

        sort(&que[1],&que[m+1],cmp1);
        int tong=1,add=1;
        for(i=1;i<=n;i++){
            if(ss[i]!=ss[i+1]){
                while(que[add].temp<ss[i]){
                    add++;
                }
                while(que[add].temp==ss[i]){
                    que[add].v=tong;
                    add++;
                }
                tong=1;
            }
            else
                tong++;
        }

        sort(&que[1],&que[m+1],cmp2);
        for(i=1;i<=m;i++){
            printf("%d\n",que[i].v);
        }
    }

    return 0;
}

ps:改了scanf的输入方式,速度提高近一倍!

原文地址:https://www.cnblogs.com/huhuuu/p/2857617.html