hdoj 5233 Gunner II 【二分】

题目链接:hdoj 5233 Gunner II

Problem Description
Long long ago, there was a gunner whose name is Jack. He likes to go hunting very much. One day he go to the grove. There are n birds and n trees. The i-th bird stands on the top of the i-th tree. The trees stand in straight line from left to the right. Every tree has its height. Jack stands on the left side of the left most tree. When Jack shots a bullet in height H to the right, the nearest bird which stands in the tree with height H will falls.

Jack will shot many times, he wants to know which bird will fall during each shot.

Input
There are multiple test cases (about 5), every case gives n, m in the first line, n indicates there are n trees and n birds, m means Jack will shot m times.

In the second line, there are n numbers h[1],h[2],h[3],…,h[n] which describes the height of the trees.

In the third line, there are m numbers q[1],q[2],q[3],…,q[m] which describes the height of the Jack’s shots.

Please process to the end of file.

[Technical Specification]

All input items are integers.

1<=n,m<=100000(10^5)

1<=h[i],q[i]<=1000000000(10^9)

Output
For each q[i], output an integer in a single line indicates the id of bird Jack shots down. If Jack can’t shot any bird, just output -1.

The id starts from 1.

Sample Input
5 5
1 2 3 4 1
1 3 1 4 2

Sample Output
1
3
5
4
2

Hint
Huge input, fast IO is recommended.

题意:给定n棵排成一排的树以及每棵树的高度,每棵树的最高处有一只小鸟。现在一个人在最左边的树旁边打m次枪。给定m次打枪的高度,问你每次是否可以打到小鸟(打掉后小鸟就不存在了),若可以输出最靠前的小鸟id,反之输出-1。

思路:sort下,然后二分查找射击高度的开始位置start和结束位置end,记录好该高度已经被打掉的小鸟数,然后这道题就可以KO了。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 1e5+10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
pii A[MAXN];
bool cmp(pii a, pii b) {
    if(a.fi != b.fi) return a.fi < b.fi;
    return a.se < b.se;
}
map<int, int> fp, tp;
int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        fp.clear(); tp.clear();
        for(int i = 1; i <= n; i++) {
            scanf("%d", &A[i].fi);
            A[i].se = i;
            fp[A[i].fi]++, tp[A[i].fi]++;
        }
        sort(A+1, A+n+1, cmp);
        for(int i = 1; i <= m; i++)
        {
            int v; scanf("%d", &v);
            if(!tp[v]) printf("-1\n");
            else {
                int pos = lower_bound(A+1, A+n+1, pii(v, 0)) - A;
                //cout << pos << " ";
                int End = pos + fp[v] - 1;
                pos = End - tp[v] + 1;
                printf("%d\n", A[pos].se);
                tp[v]--;
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值