1. 程式人生 > >sincerit 吃飯啦(二分查詢,lower_bound())

sincerit 吃飯啦(二分查詢,lower_bound())

連結:https://ac.nowcoder.com/acm/contest/289/F
來源:牛客網

題目描述
餓啦,該吃飯啦!一條街上好多家店呀,都沒吃過,作為吃貨,我一定要每家都吃一遍。就近原則,就挑一家最近的吃吧!
這條街長度為n,上面有m家店。給定q個吃貨所在的位置,請告訴每個吃貨離他最近的店有多遠。
輸入描述:
第1行含有兩個正整數n和m,含義如題目中所述。
第2行含有m個以空格分割的正整數ai,表示每家店所在的座標。
第3行含有一個正整數q,表示接下來有q個吃貨所在的座標。
第4行至第q+3行,每行內有一個正整數bi表示第i個吃貨所在的座標。
對於輸入的資料,約定:
① 1≤n≤109,1≤m≤min(n,103),1≤q≤105。
② 對於任意的1≤i≤m,有1≤ai≤n。
③ 不會有多家店在同一座標上,即當1≤i,j≤n且i≠j時,有ai≠aj。
④ 對於任意的1≤i≤q,有1≤bi≤n。
輸出描述:
對於輸入的每一個吃貨所在的位置,請輸出一行,該行內僅有一整數,表示他離與他最近的店的距離。
示例1
輸入
複製
3 1
1
3
1
2
3
輸出
複製
0
1
2

可以二分查詢找到比吃貨所在的位置大的第一個店的座標
同樣可以用lower_bound函式去查詢

#include <stdio.h>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> v;
int main() {
  int n, m, x, q, u;
  scanf("%d%d", &n, &m);
  for (int i =
0; i < m; i++) { scanf("%d", &x); v.push_back(x); } sort(v.begin(), v.end()); scanf("%d", &q); while (q--) { scanf("%d", &u); int pos = lower_bound(v.begin(), v.end(), u) - v.begin(); // 查詢大於或等於u的第一個元素位置 if (pos == v.size()) printf("%d\n", u - v[pos-1]); // 返回了長度說明沒找到
else if (pos == 0) printf("%d\n", v[pos]-u); else printf("%d\n", v[pos]-u > u-v[pos-1] ? u-v[pos-1]:v[pos]-u); } return 0; }