Find the hotel(HDU-3193) (RMQ)

Find the hotel

Problem Description
Summer again! Flynn is ready for another tour around. Since the tour would take three or more days, it is important to find a hotel that meets for a reasonable price and gets as near as possible!
But there are so many of them! Flynn gets tired to look for any. It’s your time now! Given the (pi, di) for a hotel hi, where pi stands for the price and di is the distance from the destination of this tour, you are going to find those hotels, that either with a lower price or lower distance. Consider hotel h1, if there is a hotel hi, with both lower price and lower distance, we would discard h1. To be more specific, you are going to find those hotels, where no other has both lower price and distance than it. And the comparison is strict.

Input
There are some cases. Process to the end of file.
Each case begin with N (1 <= N <= 10000), the number of the hotel.
The next N line gives the (pi, di) for the i-th hotel.
The number will be non-negative and less than 10000.

Output
First, output the number of the hotel you find, and from the next line, print them like the input( two numbers in one line). You should order them ascending first by price and break the same price by distance.

Sample Input
3
15 10
10 15
8 9
Sample Output
1
8 9

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3193

题目大意:
给你n个旅馆的p(价格)和d(距离值),然后要你输出所有的“目的旅馆”。如果对于旅馆i来说,没有其他任何一个旅馆的px和dx值同时小于pi和di。那么旅馆i可以算一个“目的旅馆”。
输出:
先输出目的旅馆的个数。
再按p从小到大(如p相同,d从小到大)的顺序输出所有目的旅馆的p和d值。

题目分析:
本题的要求很特殊,注意是要一个旅馆的p和d属性同时小于另外一个旅馆才能判断第二个旅馆不是目的旅馆。
看下面的输入例子: 输出却也是:
3 ——————> 3
1 10 ——————> 1 10
2 5 ——————> 2 5
2 6 ——————> 2 6
本题采用标记法,把二维属性p和d变成一维,只考虑d就行。首先读入所有的旅店,然后对于每个读入的旅店更新一个数组a[],
其中a[p]=d表示所有价格为p的旅店中最短的距离是d.
然后再扫描一遍所有旅店,假设当前扫描到的旅店为(pi , di),那么如果我们已经知道了价格小于pi的所有旅店中距离最小值为d且这个(d小于di),那么肯定抛弃(pi , di) ,否则留下(pi, di).
上述查询最小d值的过程就是getMin(0,pi-1).所以需要RMQ查询.由于p和d可能为0,所以我们在读入的时候把所有p和d值加1,然后最后输出的时候把所有p,d值减1即可.
本算法总的复杂度是O(nlogn).
**

代码:

**

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
typedef long long LL;
const int N=10099;
int dp[N][30],d[N];  //这里用d数组存储p价格的最短距离。
struct sky
{
    int p;
    int d;
}a[N],num[N];
bool cmp(sky a,sky b)
{
    if(a.p!=b.p)
        return a.p<b.p;
    else
        return a.d<b.d;
}
void ST(int n)
{
    for(int i=0;i<n;i++)
        dp[i][0]=d[i];
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=0 ; i+(1<<j)-1<n ;i++)
        {
            dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
        }
    }
}
int RMQ(int l,int r)
{
    int k=log(r-l+1.0)/log(2.0);
    int a=dp[l][k];
    int b=dp[r-(1<<k)+1][k];
    return min(a,b);
}
int main()
{
    int n,k;
    while(scanf("%d",&n)!=EOF)
    {
        k=0;
        memset(a,0,sizeof(a));
        memset(num,0,sizeof(num));
        memset(d,0x3f,sizeof(d));
        int p,dis;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p,&dis);
            a[i].p=p;
            a[i].d=dis; 
            d[p]=min(d[p],dis);
        }
        sort(a,a+n,cmp);
        ST(N); //这里传入N 就可以以为价格最高也不会超过N 
        //但是不知到为什么这里传入n也对,谁知道告诉我一下
        num[k].p=a[0].p;
        num[k++].d=a[0].d;
        for(int i=1;i<n;i++)
        {
            if(a[i].p==0) // 如果价钱为 0 的话要特判,此时不存在价格比 0 还小的
            {
                num[k++]=a[i];
                continue;
            }
            int x=RMQ(0,a[i].p-1);
            if(a[i].d>x) //如果在0到p-1的 价格能找到距离比这个旅馆距离小的就跳过
                continue;
            num[k].p=a[i].p;
            num[k++].d=a[i].d;
        }
        printf("%d\n",k);
        for(int i=0;i<k;i++)
        {
            printf("%d %d\n",num[i].p,num[i].d);
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值