侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 551 篇文章
  • 累计创建 117 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

【哈希表, 二分查找】保龄球

GabrielxD
2022-12-19 / 0 评论 / 0 点赞 / 13 阅读 / 840 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-12-19,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

P1918 保龄球


题目描述

DL 算缘分算得很烦闷,所以常常到体育馆去打保龄球解闷。因为他保龄球已经打了几十年了,所以技术上不成问题,于是他就想玩点新花招。

DL 的视力真的很不错,竟然能够数清楚在他前方十米左右每个位置的瓶子的数量。他突然发现这是一个炫耀自己好视力的借口——他看清远方瓶子的个数后从某个位置发球,这样就能打倒一定数量的瓶子。

1 OOO

2 OOOO

3 O

4 OO

如上图,每个“O”代表一个瓶子。如果 DL 想要打倒 3 个瓶子就在 1 位置发球,想要打倒 4 个瓶子就在 2 位置发球。

现在他想要打倒 m 个瓶子。他告诉你每个位置的瓶子数,请你给他一个发球位置。

输入格式

第一行包含一个正整数 n,表示位置数。

第二行包含 n 个正整数,第 i 个数。表示第 i 个位置的瓶子数,保证各个位置的瓶子数不同。

第三行包含一个正整数 Q,表示 DL 发球的次数。

第四行至文件末尾,每行包含一个正整数 m,表示 DL 需要打倒 m 个瓶子。

输出格式

共 Q 行。每行包含一个整数,第 i 行的整数表示 DL 第 i 次的发球位置。若无解,则输出 0。

样例 #1

样例输入 #1

5
1 2 4 3 5
2
4
7

样例输出 #1

3
0

提示

【数据范围】

对于 50%的数据,1 ≤ n,Q ≤ 1000,1 ≤ai,M ≤ 10^5

对于 100%的数据,1 ≤ n,Q ≤ 100000,1 ≤ai,M ≤ 10^9

解题

方法一:哈希表

思路

把每个位置的瓶子数及位置编号对应存入哈希表,对每个询问都在哈希表中取,取不到说明没有。

代码

#include <iostream>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int N = 1e5 + 10;
int n, a[N], q;
unordered_map<int, int> mp;

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        int x;
        scanf("%d", &x);
        a[i] = x;
        mp[x] = i;
    }
    scanf("%d", &q);
    while (q--) {
        int x;
        scanf("%d", &x);
        if (mp.find(x) == mp.end()) puts("0");
        else printf("%d\n", mp[x]);
    }

    return 0;
}

方法二:二分查找

思路

把位置与其瓶子数构建为一个结构体,结构体数组按照瓶子数量排序,二分查找找到需要的瓶子数。

代码

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;
struct Row {
    int x, i;
} a[N];
int n, q;

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        int x;
        scanf("%d", &a[i].x);
        a[i].i = i;
    }
    sort(a + 1, a + n + 1, [](Row& j, Row& k) { return j.x < k.x; });
    scanf("%d", &q);
    while (q--) {
        int x;
        scanf("%d", &x);
        int l = 1, r = n;
        while (l < r) {
            int m = l + r >> 1;
            if (a[m].x >= x) r = m;
            else l = m + 1;
        }
        if (a[l].x != x) puts("0");
        else printf("%d\n", a[l].i);
    }

    return 0;
}
0

评论区