Find the hotel
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 739 Accepted Submission(s): 249
But there are so many of them! Flynn gets tired to look for any. It’s your time now! Given the (p i, d i) for a hotel h i, where p i stands for the price and d i 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 h 1, if there is a hotel h i, 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.
Each case begin with N (1 <= N <= 10000), the number of the hotel.
The next N line gives the (p i, d i) for the i-th hotel.
The number will be non-negative and less than 10000.
3 15 10 10 15 8 9
1 8 9
题目大意:
给你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;
}
#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;
}