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

 

  

转载于:https://www.cnblogs.com/Bw98blogs/p/8343212.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值