POJ #2726 Holiday Hotel

Posted 大峰子的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ #2726 Holiday Hotel相关的知识,希望对你有一定的参考价值。

Description


 

Mr. and Mrs. Smith are going to the seaside for their holiday. Before they start off, they need to choose a hotel. They got a list of hotels from the Internet, and want to choose some candidate hotels which are cheap and close to the seashore. A candidate hotel M meets two requirements: 
  1. Any hotel which is closer to the seashore than M will be more expensive than M. 
  2. Any hotel which is cheaper than M will be farther away from the seashore than M.

Input

There are several test cases. The first line of each test case is an integer N (1 <= N <= 10000), which is the number of hotels. Each of the following N lines describes a hotel, containing two integers D and C (1 <= D, C <= 10000). D means the distance from the hotel to the seashore, and C means the cost of staying in the hotel. You can assume that there are no two hotels with the same D and C. A test case with N = 0 ends the input, and should not be processed.

Output

For each test case, you should output one line containing an integer, which is the number of all the candidate hotels.

Sample Input

5
300 100
100 300
400 200
200 400
100 500
0

Sample Output

2

题意


 

  有N个旅店,每个旅店有两个属性,距离D,价格C。现在想要找出这样的旅店,它们满足以下两个条件:

  1.比M近的,价格比它高

  2.比M便宜的,距离比它远

  求有多少个这样的旅店  

 

INPUT


 

  头一行输入整数对的个数 N(1<= N <= 10000) ,之后的 N 行分别输入 N 对整数对 (dist, cost) 。

  输入 N = 0 时结束程序。

  

 

OUTPUT


 

  输出候选旅馆的个数 ,占一行。

  

 

思路


 

  一战Time Limit Exceeded ... 分析了一下,由于输出的只是一个值而不是各个旅馆的信息,那就不用另开一个集合 B,直接在原集合里原址操作即可。通过快排原址排序,注意一趟排序只能对一个属性进行排序,我选择对距离进行排序。排序好了之后,记录离海边最近的旅馆之中的最低费用,以它为依据向下比较,直到找到费用比它少的旅馆,则说明找到了一个候选旅馆。因为虽然该旅馆离海边的距离更远,但是费用却更小。

 

  下面是我的解法。算法的时间复杂度是 O(n·lgn)。

#include<iostream>
#include<vector>
using std::cin;
using std::cout;
using std::endl;
using std::vector;

struct Hotel {
    int dist;
    int cost;
};

void exchange (vector<Hotel> &A, int i, int j) {
    Hotel temp = A[i];
    A[i] = A[j];
    A[j] = temp;
}

int partition (vector<Hotel> &A, int left, int right) {
    int x = A[right].dist;
    int i = left - 1;
    for (int j = left; j < right; j++) {
        if (A[j].dist <= x) {
            i++;
            exchange (A, i, j);
        }
    }
    exchange (A, i+1, right);
    return i+1;
}

void quickSort (vector<Hotel> &A, int left, int right) {
    if (left < right) {
        int pivot = partition(A, left, right);
        quickSort (A, left, pivot-1);
        quickSort (A, pivot+1, right);
    }
}

int main (void) {
    int n;
    vector<Hotel> A;
    while (cin >> n && n) {
        A.resize(n);
        for (int i = 0; i < n; ++i) {
            cin >> A[i].dist >> A[i].cost;
        }
        //sort set A 
        quickSort(A, 0, n-1);      
        //compute candidate hotel num
        int counter = 1;
        int min = A[0].cost;
        int k;//记录距离最小时费用最小的元素的下标
        for (k = 1; (k < n) && (A[k].dist == A[0].dist); ++k) {
            if (min > A[k].cost) {
                min = A[k].cost;
            }
        }
        for (int i = k; i < n; ++i) { //自k下标起,之后的元素只要费用比min小则满足条件
            if (min > A[i].cost) {
                counter++;
                min = A[i].cost;
            }
        }
        cout << counter << endl;
        A.clear();
        vector<Hotel>().swap(A);
    }//while (cin >> n && n) 
    return 0;
}
View Code

  当然,如果进行两次排序,一次对距离,另一次对费用,记录首元素的费用并向下比较,也是OK的:

#include<iostream>
#include<algorithm>
#include<vector>
using std::cin;
using std::cout;
using std::endl;
using std::vector;

struct Hotel {
    int dist;
    int cost;
};

bool cmp (const Hotel& a, const Hotel& b) {
    if (a.dist == b.dist) {
        return a.cost < b.cost;
    }
    return a.dist < b.dist;
}

int main (void) {
    int n;
    vector<Hotel> A;
    while (cin >> n && n) {
        A.resize(n);
        for (int i = 0; i < n; ++i) {
            cin >> A[i].dist >> A[i].cost;
        }
        //sort set A 
        //quickSort(A, 0, n-1);
        std::sort(A.begin(), A.end(), cmp);
        //compute candidate hotel num
        int counter = 1;
        int min = A[0].cost;
        for (int i = 1; i < n; i++) {
            if (min > A[i].cost ) {
                ++counter;
                min = A[i].cost;
            }
        }
        cout << counter << endl;
        A.clear();
        vector<Hotel>().swap(A);
    }//while (cin >> n && n) 
    return 0;
}
View Code

 

  

以上是关于POJ #2726 Holiday Hotel的主要内容,如果未能解决你的问题,请参考以下文章

线段树区间合并POJ3667-Hotel

[POJ3667]Hotel

Hotel POJ - 3667 (区间合并 + 区间查询)

poj 3667 Hotel (线段树的合并操作)

POJ 3667 Hotel

POJ 3667 Hotel