Find the hotel HDU - 3193

原题链接
考察:排序,前缀和思想
错误思路:
  建立d,p的树状数组,对于每一个查询是否有 <\(d[i]\)&&<\(p[i]\)
错误原因:
  显然p,d是一体的不能分开.
正确思路:
  结构体排序按p,d优先顺序排序,对于每一个\(p[i]\),查询\(<p[i]\)的最小\(d[i]\),如果\(>=d[i]\)则当前旅馆计入答案
  计入最小值直接用前缀的\(f\)数组,根本没必要用RMQ

Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef pair<int, int> PII;
const int N = 10010;
struct cmp{
    bool operator()(PII x,PII y){
        if(x.first==y.first)
            return x.second < y.second;
        return x.first < y.first;
    }
};
PII p[N],ans[N];
int n,f[N],cnt;
void init()
{
    memset(f, 0x3f, sizeof f);
    for (int i = 1; i <= n;i++)
        f[i] = min(f[i - 1], p[i].second);
}
int main()
{

    while(scanf("%d",&n)!=EOF)
    {
    	cnt = 0;
    	for (int i = 1; i <= n;i++)
        	scanf("%d%d", &p[i].first, &p[i].second);
    	sort(p + 1, p + n + 1);
    	init();
    	for (int i = 1,j=1; i <= n;i++)
    	{
        	if(p[j].first!=p[i].first) j = i;
        	if(f[j-1]>=p[i].second)
            	ans[++cnt] = p[i];
    	}
    	printf("%d\n", cnt);
    	for (int i = 1; i <= cnt;i++)
       		printf("%d %d\n", ans[i].first, ans[i].second);
	}
    return 0;
}

posted @ 2021-07-03 20:32  acmloser  阅读(26)  评论(0编辑  收藏  举报