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:
- Any hotel which is closer to the seashore than M will be more expensive than M.
- 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 0Sample 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)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
当然,如果进行两次排序,一次对距离,另一次对费用,记录首元素的费用并向下比较,也是OK的:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }