Vasiliy likes to rest after a hard work, so you may often meet him in some bar nearby. As all programmers do, he loves the famous drink “Beecola”, which can be bought in n different shops in the city. It’s known that the price of one bottle in the shop i is equal to xi coins.
Vasiliy plans to buy his favorite drink for q consecutive days. He knows, that on the i-th day he will be able to spent mi coins. Now, for each of the days he want to know in how many different shops he can buy a bottle of “Beecola”.
Input
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of shops in the city that sell Vasiliy’s favourite drink.
The second line contains n integers xi (1 ≤ xi ≤ 100 000) — prices of the bottles of the drink in the i-th shop.
The third line contains a single integer q (1 ≤ q ≤ 100 000) — the number of days Vasiliy plans to buy the drink.
Then follow q lines each containing one integer mi (1 ≤ mi ≤ 109) — the number of coins Vasiliy can spent on the i-th day.
Output
Print q integers. The i-th of them should be equal to the number of shops where Vasiliy will be able to buy a bottle of the drink on the i-th day
//
Input
5
3 10 8 6 11
4
1
10
3
11
Output
0
4
1
5
//这个是最一开始用的二分,代码较长,但是好理解一些
#include <iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int EF(int arr[], int len, int num)//稍作修改的二分
{
int left=1;
int right=len;
int mid;
int ans;
while(left<=right)
{
mid=(left+right)/2;
if(arr[mid]<=num)
{
ans=mid;
left=mid+1;
}
else
{
right=mid-1;
}
}
return ans;//返回最后找到的下标
}
int main()
{
int n,q,m;
int a[100001],b;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
scanf("%d",&q);
for(int i=0;i<q;i++)
{
m=0;
int mins,maxs,mid;
mins=1;maxs=n;
scanf("%d",&b);
if(b<a[1])
m=0;
else if(b>=a[n])
m=n;
else
m=EF(a,n,b);
printf("%d\n",m);
}
}
}
//不难的一道二分题目,当时因为sort(a+1,a+n+1)忘了加一。。。。连续WA好几次
说多了都是泪
//做一个中间值,类似于dp
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int n,q,m;
int a[100005],b[100005],mid[100005];
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
mid[a[i]]++;
}
int j=1;
if(mid[0]==0)
b[0]=0;
else if(mid[0]==1)
b[0]=1;
for(int i=1;i<=100000;i++)
{
b[i]=b[i-1]+mid[i];//计算出比比某一个数小的有多少个,存到数组里
}
scanf("%d",&q);
while(q--)
{
scanf("%d",&m);
if(m<=100000)
printf("%d\n",b[m]);
else
printf("%d\n",b[100000]);
}
}
}
第三种,最简单的做法
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int a1[100005],a2[100005];
int n=0,m=0;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a1[i]);
}
scanf("%d",&m);
sort(a1,a1+n);
for(int i=0;i<m;i++)
{
scanf("%d",&a2[i]);
//减去a1的首地址得到下标即小于等于a2[i]的个数
int q=upper_bound(a1,a1+n,a2[i])-a1;
printf("%d\n",q);
}
}
}
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。