简单题练习——数字在排序数组中出现的次数

题目描述:
统计一个数字在排序数组中出现的次数。
输入:

每个测试案例包括两行:

第一行有1个整数n,表示数组的大小。1<=n <= 10^6。

第二行有n个整数,表示数组元素,每个元素均为int。

第三行有1个整数m,表示接下来有m次查询。1<=m<=10^3。

下面有m行,每行有一个整数k,表示要查询的数。

输出:
对应每个测试案例,有m行输出,每行1整数,表示数组中该数字出现的次数。

样例输入:
81 2 3 3 3 3 4 513
样例输出:
4
总结:卡了好久,总是超时,最后把最多1k的数值的输入输出都改成scanf printf才勉强通过,cin 效率差这么多吗(超过200ms)按理说相对1M的输入这里1K基本可以忽略呀,
 
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
int num[1000000];
 
int biSearchFirst( int n, int val) //第一个
{
     int low=0;
     int high=n-1;
     while (low<high)
     {
         int mid=(low+high)/2;
         if (num[mid]<val)
             low = mid+1;
         else
             high = mid;
     }
     return low;
}
 
int biSearchLast( int n, int val) //第一个大于的
{
     int low=0;
     int high=n-1;
     while (low<high)
     {
         int mid=(low+high)/2;
         if (num[mid]>val)
             high = mid;
         else
             low=mid+1;
         /*int mid=(low+high)/2;//弄了个死循环
         if(num[mid]>val)
             high = mid-1;
         else
             low=mid;*/
     }
     if (high==n-1 && num[high]==val)
         high++;
     
     return high;
}
 
int OccursNum( int n, int val)
{
     int start = biSearchFirst(n,val);
     int end = biSearchLast(n,val);
     if (start!=-1 && end!=-1)
         return end-start /*+1*/ ;
     else
         return 0;
}
int main()
{
     //freopen("in.txt","r",stdin);
     int n;
     while (cin>>n)
     {
         for ( int i=0; i<n; i++)
             scanf ( "%d" ,num+i);
         int m;
         scanf ( "%d" ,&m);
         //cin>>m;
         for ( int i=0; i<m; i++)
         {
             int temp;
             scanf ( "%d" ,&temp);
             //cin>>temp;
             printf ( "%d\n" ,OccursNum(n,temp));
             //cout<<OccursNum(n,temp)<<endl;
         }
     }
     return 0;
}
/**************************************************************
     Problem: 1349
     User: xjbscut
     Language: C++
     Result: Accepted
     Time:1000 ms
     Memory:5416 kb
****************************************************************/
后面把k次查询排序组织按需查询缩小后面的查询范围效率也没有太大优化(一组简单测试样例没通过,有点小bug)
 
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <vector>
using namespace std;
int num[1000000];
struct ansInfo
{
     int id;
     int queryNum;
     int val;
};
ansInfo Ans[1000];
int biSearchFirst( int start, int end, int val)
{
     int low=start;
     int high=end;
     while (low<=high)
     {
         int mid=(low+high)/2;
         if (num[mid]>val)
             high = mid-1;
         else if (num[mid]<val)
             low = mid+1;
         else
         {
             if (mid>0 && num[mid-1]==val)
                 high=mid-1;
             else
                 return mid;
         }
     }
}
 
int biSearchLast( int start, int end, int val)
{
     int low=start;
     int high=end;
     while (low<=high)
     {
         int mid=(low+high)/2;
         if (num[mid]>val)
             high = mid-1;
         else if (num[mid]<val)
             low = mid+1;
         else
         {
             if (mid<end && num[mid+1]==val)
                 low=mid+1;
             else
                 return mid;
         }
     }
     return -1;
}
 
//int OccursNum(int n, int val)
//{
//  int start = biSearchFirst(n,val);
//  int end = biSearchLast(n,val);
//  if(start!=-1 && end!=-1)
//      return end-start+1;
//  else
//      return 0;
//}
bool cmp1( const ansInfo &a, const ansInfo &b)
{
     return a.queryNum<b.queryNum;
}
bool cmp2( const ansInfo &a, const ansInfo &b)
{
     return a.id<b.id;
}
int main()
{
     //freopen("in.txt","r",stdin);
     int n;
     while (cin>>n)
     {
         for ( int i=0; i<n; i++)
             scanf ( "%d" ,num+i);
         int m;
         scanf ( "%d" ,&m);
         //cin>>m;
         ansInfo temp;
         for ( int i=0; i<m; i++)
         {
             temp.id=i;
             scanf ( "%d" ,&temp.queryNum);
             //cin>>temp.queryNum;
             Ans[i]=temp;
         }
         sort(Ans,Ans+m,cmp1);
         int first,last;
         first=biSearchFirst(0,n-1,Ans[0].queryNum);
         last=biSearchLast(0,n-1,Ans[0].queryNum);
         Ans[0].val=last-first+1;
         for ( int i=1; i<m; i++)
         {
             if (Ans[i].queryNum == Ans[i-1].queryNum)
                 Ans[i].val=Ans[i-1].val;
             else
             {
                 first=biSearchFirst(last+1,n-1,Ans[i].queryNum);
                 last=biSearchLast(first,n-1,Ans[i].queryNum);
                 Ans[i].val=last-first+1;
             }
         }
         sort(Ans,Ans+m,cmp2);
         for ( int i=0; i<m; i++)
             printf ( "%d\n" ,Ans[i].val);
             //cout<<Ans[i].val<<endl;
     }
     return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值