18.9.11 周二 基础算法篇:二分 Interesting drink

本文介绍了一种算法问题,即给定多个商店中饮料的价格及每天可支配的金额,计算每天能在多少个商店购买到饮料。通过不同算法实现,如暴力求解、使用upper_bound函数及二分查找等,来解决这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Interesting drink

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.

Example

Input

5
3 10 8 6 11
4
1
10
3
11

Output

0
4
1
5

Note

On the first day, Vasiliy won't be able to buy a drink in any of the shops.

On the second day, Vasiliy can buy a drink in the shops 1, 2, 3 and 4.

On the third day, Vasiliy can buy a drink only in the shop number 1.

Finally, on the last day Vasiliy can buy a drink in any shop.

 

AC代码1(类似暴力):

#include"stdio.h"
#include"iostream"
#include"math.h"
#include"string.h"
#include"algorithm"
using namespace std;

int n ,m ;
int number[100005];
int tem[100005];
int money[100005];
//
int main()
{
    memset(number,0,sizeof(number));
    memset(tem,0,sizeof(tem));
    while(~scanf("%d",&n))
    {
        for(int i = 0;i<n;i++)
        {
            scanf("%d",&money[i]);
            tem[money[i]] ++;
        }
        if(tem[0] == 0)
        number[0] = 0;
        else if(tem[0] == 1) number[0] = 1;
        for(int i = 1;i<=100000;i++)
        {
            number[i] = tem[i] + number[i-1];
        }
        scanf("%d",&m);
        int k;
        for(int i = 0;i<m;i++)
        {
            scanf("%d",&k);
            //防越界(K取值范围大)
            if(k<=100000)
            cout<<number[k]<<endl;
            else
                cout<<number[100000]<<endl;
        }
        
    }
}

AC代码2(upper_bound):

#include"stdio.h"
#include"iostream"
#include"math.h"
#include"string.h"
#include"algorithm"
using namespace std;
// arr1 价格
// arr2 带的钱
int arr1[100005];
int arr2[100005];
int main()
{
    
    int n = 0 , m = 0 ;
    while(scanf("%d",&n) != EOF)
    {
        for(int i = 0;i<n;i++) scanf("%d",&arr1[i]);
        scanf("%d",&m);
        sort(arr1,arr1+n);
        int cnt = 0;
        //
        for(int i = 0;i< m;i++)
        {
            scanf("%d",&arr2[i]);
            cnt = 0;
            //减去数组arr1的初始地址,计算出个数
            long int  q = upper_bound(arr1,arr1+n,arr2[i])-arr1;
            cout<<q<<endl;
        }
    }
    
    return 0;
}

AC代码3(二分):…

#include"stdio.h"
#include"iostream"
#include"math.h"
#include"string.h"
#include"algorithm"
using namespace std;
// arr1 价格
// arr2 带的钱
int arr1[100005];
int arr2[100005];

int binarySearch(int arr[], int len, int key)
{
    int left = 0;
    int right = len - 1;
    int mid;
    int ans;
    while (left <= right) {
        mid = (left + right) / 2;
        if (key <= arr[mid]) {//key在左边
            right = mid - 1;
            ans  = mid;
        } else  {//key在右边
            left = mid + 1;
        }
        return ans;
    }
    return -1;
}

int main()
{
    int n,m;
    while(~scanf("%d",&n))
    {
        for(int i = 0;i<n;i++)
            scanf("%d",&arr1[i]);
        sort(arr1,arr1+n);
        //
        scanf("%d",&m);
        for(int i =0;i<m;i++)
        {
            scanf("%d",&arr2[i]);
            //控制时间
            if(arr2[i] >= arr1[n-1]) cout<<n<<endl;
            else if(arr2[i] < arr1[0]) cout<<"0"<<endl;
            //二分
            else
            {
                int l = 0;
                int r = n-1;
                int ans = 0;
                while(l<=r)
                {
                    int mid = (r + l)/2;
                    if(arr1[mid] <= arr2[i])
                    {
                       l = mid + 1;
                        ans = mid;
                    }
                    else
                    {
                         r = mid - 1;
                        
                    }
                }
                cout<<ans+1<<endl;
            }
        }
            
    }
}

小细节一定要看好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值