- 题目描述:
-
统计一个数字在排序数组中出现的次数。
- 输入:
-
每个测试案例包括两行:
第一行有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>usingnamespacestd;intnum[1000000];intbiSearchFirst(intn,intval)//第一个{intlow=0;inthigh=n-1;while(low<high){intmid=(low+high)/2;if(num[mid]<val)low = mid+1;elsehigh = mid;}returnlow;}intbiSearchLast(intn,intval)//第一个大于的{intlow=0;inthigh=n-1;while(low<high){intmid=(low+high)/2;if(num[mid]>val)high = mid;elselow=mid+1;/*int mid=(low+high)/2;//弄了个死循环if(num[mid]>val)high = mid-1;elselow=mid;*/}if(high==n-1 && num[high]==val)high++;returnhigh;}intOccursNum(intn,intval){intstart = biSearchFirst(n,val);intend = biSearchLast(n,val);if(start!=-1 && end!=-1)returnend-start/*+1*/;elsereturn0;}intmain(){//freopen("in.txt","r",stdin);intn;while(cin>>n){for(inti=0; i<n; i++)scanf("%d",num+i);intm;scanf("%d",&m);//cin>>m;for(inti=0; i<m; i++){inttemp;scanf("%d",&temp);//cin>>temp;printf("%d\n",OccursNum(n,temp));//cout<<OccursNum(n,temp)<<endl;}}return0;}/**************************************************************Problem: 1349User: xjbscutLanguage: C++Result: AcceptedTime:1000 msMemory:5416 kb****************************************************************/
后面把k次查询排序组织按需查询缩小后面的查询范围效率也没有太大优化(一组简单测试样例没通过,有点小bug)
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <map>#include <vector>usingnamespacestd;intnum[1000000];structansInfo{intid;intqueryNum;intval;};ansInfo Ans[1000];intbiSearchFirst(intstart,intend,intval){intlow=start;inthigh=end;while(low<=high){intmid=(low+high)/2;if(num[mid]>val)high = mid-1;elseif(num[mid]<val)low = mid+1;else{if(mid>0 && num[mid-1]==val)high=mid-1;elsereturnmid;}}}intbiSearchLast(intstart,intend,intval){intlow=start;inthigh=end;while(low<=high){intmid=(low+high)/2;if(num[mid]>val)high = mid-1;elseif(num[mid]<val)low = mid+1;else{if(mid<end && num[mid+1]==val)low=mid+1;elsereturnmid;}}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;//}boolcmp1(constansInfo &a,constansInfo &b){returna.queryNum<b.queryNum;}boolcmp2(constansInfo &a,constansInfo &b){returna.id<b.id;}intmain(){//freopen("in.txt","r",stdin);intn;while(cin>>n){for(inti=0; i<n; i++)scanf("%d",num+i);intm;scanf("%d",&m);//cin>>m;ansInfo temp;for(inti=0; i<m; i++){temp.id=i;scanf("%d",&temp.queryNum);//cin>>temp.queryNum;Ans[i]=temp;}sort(Ans,Ans+m,cmp1);intfirst,last;first=biSearchFirst(0,n-1,Ans[0].queryNum);last=biSearchLast(0,n-1,Ans[0].queryNum);Ans[0].val=last-first+1;for(inti=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(inti=0; i<m; i++)printf("%d\n",Ans[i].val);//cout<<Ans[i].val<<endl;}return0;}
本文介绍了一种解决排序数组中特定数字出现次数问题的算法,包括使用二分查找优化查询效率,以及如何处理大规模输入数据。通过案例分析和代码实现,展示了在面对大量数据时如何优化算法性能。
2602

被折叠的 条评论
为什么被折叠?



