HDU 3193 Find the hotel(RMQ)

来源:互联网 发布:linux保存vi修改文件 编辑:程序博客网 时间:2024/06/03 00:03

HDU 3193 Find the hotel(RMQ)

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

      1    10

      2    5

      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查询.由于pd可能为0,所以我们在读入的时候把所有pd值加1,然后最后输出的时候把所有p,d值减1即可.

      本算法总的复杂度是O(nlogn).

AC代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN =10000+100;int a[MAXN];int dmin[MAXN][20];void initMin(int n,int d[]){    for(int i=0; i<=n; i++)dmin[i][0]=d[i];    for(int j=1; (1<<j)<=n; j++)        for(int i=1; i+(1<<j)-1<=n; i++)            dmin[i][j] = min(dmin[i][j-1] , dmin[i+(1<<(j-1))][j-1]);}int getMin(int L,int R){    int k=0;    while((1<<(k+1))<=R-L+1)k++;    return min(dmin[L][k] , dmin[R-(1<<k)+1][k]);}struct node{    int p,d;    bool operator <(const node &b)const    {        return p<b.p || (p==b.p && d<b.d);    }} node1[MAXN],node2[MAXN];int main(){    int n;    while(scanf("%d",&n)==1&&n)    {        for(int i =0; i<=10000+100; i++)            a[i]=1000000;        for(int i=1; i<=n; i++)        {            int p,d;            scanf("%d%d",&p,&d);            p++;            d++;            node1[i].p=p;            node1[i].d=d;            a[p] = min(a[p],d);        }        initMin(MAXN,a);        int cnt=0;        for(int i=1; i<=n; i++)        {            int p,d;            p = node1[i].p;            d = node1[i].d;            if(p==1)//这个需要特殊处理,否则下面会getMin(1,0)了            {                node2[++cnt]  =node1[i];            }            else            {                int d_min = getMin(1,p-1);                if(d<=d_min)                {                    node2[++cnt]  =node1[i];                }            }        }        sort(node2+1,node2+1+cnt);        printf("%d\n",cnt);        for(int i=1; i<=cnt; i++)            printf("%d %d\n",node2[i].p-1,node2[i].d-1);    }    return 0;}

0 0
原创粉丝点击