Find the hotel HDU - 3193(RMQ)

题意:

   有n个旅馆,从这n个旅馆中找出若干个旅馆,使得这若干个旅馆满足这样的条件:不能从其它和剩下的旅馆中找到一个价格和距离都小于这个旅馆的旅馆。。。

解析:

 按price 排序,若price相同, 则按距离排序

 然后遍历每一个旅馆,在处理当前 旅馆时,二分在price小于当前旅馆price的旅馆中 找到最后一个price小于当前旅馆price的旅馆(因为可能price相同)

 然后rmq求距离最小值就可 

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 10010, INF = 0x7fffffff;
int d[maxn][20];
int n;
struct node
{
    int price, dis;
}Node[maxn];

bool cmp(node a, node b)
{
    if(a.price == b.price) return a.dis < b.dis;
    return a.price < b.price;
}

int rmq(int l, int r)
{
    int k = 0;
    while((1<<(k+1)) <= r-l+1) k++;
    return min(d[l][k], d[r-(1<<k)+1][k]);

}


int main()
{
    while(~scanf("%d", &n))
    {
        vector<node> v;
        rep(i, 0, n)
        {
            scanf("%d%d", &Node[i].price, &Node[i].dis);
        }
        sort(Node, Node+n, cmp);
        rap(i, 0, n)
            d[i][0] = Node[i].dis;
        for(int j=1; (1<<j) <= n; j++)
            for(int i=0; i+(1<<j)-1 < n; i++)
                d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);

        v.push_back(Node[0]);
        for(int i=1; i<n; i++)
        {
            int x = 0, y = i;   //lower_bound实现  返回第一次出现当前price的位置
            while(x < y)
            {
                int mid = x + (y-x) / 2;
                if(Node[mid].price >= Node[i].price) y = mid;
                else x = mid + 1;
            }
            if(x == 0)// 如果当前price就是最小的
            {
                v.push_back(Node[i]);
                continue;
            }
            int h = rmq(0, x-1);  //查询0到x-1中是否存在一个dis小于当前dis
            if(h >= Node[i].dis)  //如果不存在
                v.push_back(Node[i]);
        }
        printf("%d\n", v.size());
        for(int i=0; i<v.size(); i++)
            printf("%d %d\n", v[i].price, v[i].dis);

    }


    return 0;
}

 

posted @ 2018-08-09 17:59  WTSRUVF  阅读(246)  评论(0编辑  收藏  举报