- 题目描述:
-
统计一个数字在排序数组中出现的次数。
- 输入:
-
每个测试案例包括两行:
第一行有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;
}