还是贪心法。把原始数据排序,排序的规则是先按照右端点排序,右端点相同的情况下,再按照左端点排序。然后最左边开始遍历线段,取第一个线段的右端点,判断是否和第二个线段的右端点相等,如果相等,肯定可以缩短为两个相邻的;如果不想等,再判断第一个右端点是否小于第二个左端点,如果小于,则中间肯定有空隙,标记加1,然后在拿第二个的右端点和第三个线段继续同理比较;如果大于,则说明第二个的可以紧邻放在第一个的最右边,相当于把第一个线段放大,这里就是贪心的思想了。
PS:刚开始写cmp函数不小心写了引用,直接CE了一把。
AC代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cctype> #include <cstring> #include <string> #include <sstream> #include <vector> #include <set> #include <map> #include <algorithm> #include <stack> #include <queue> #include <bitset> #include <cassert> #include <cmath> #include <functional> using namespace std; typedef pair<int, int> Pair; int n; // 先按照右端点从小到大排序,右端点相同的情况下按左端点排序 bool cmp(Pair A, Pair B) { if (A.second != B.second) { return A.second < B.second; } return A.first < B.first; } int main() { ios::sync_with_stdio(false); int T; cin >> T; while (T--) { cin >> n; vector<Pair> A; int x, y; for (int i = 0; i < n; i++) { cin >> x >> y; A.push_back(Pair(x, y)); } sort(A.begin(), A.end(), cmp); // 贪心求解 int ret = 1, right = A[0].second; for (int i = 1; i < n; i++) { if (right != A[i].second) { if (right < A[i].first) { ret++; right = A[i].second; } else { right++; // 这里就是贪心处理 } } } cout << ret - 1 << endl; } return 0; }
原文地址:http://blog.csdn.net/zyq522376829/article/details/46646669