USACO SEC.1.2 No.1 Milking Cows
题意:给出N个村民,每个村民每天早上起来在闭区间[a, b]挤牛奶,求至少一个村民挤牛奶的最长时间, 和没有村民挤牛奶的最长时间
解法:经典的区间合并问题, 将区间的端点作为事件,从左往右用扫描线进行扫描,
需要注意的是,如果有结束事件和开始事件相同,先处理开始事件
/* ID: lsswxr1 PROG: milk2 LANG: C++ */ #include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <string> #include <fstream> using namespace std; ///宏定义 const int INF = 1000000000; const int MAXN = 10100; const int maxn = MAXN; ///全局变量 和 函数 #define USACO #ifdef USACO #define cin fin #define cout fout #endif ////////////////////////////////////////////////////////////////////////// int N; struct events { int t; bool flag; bool operator < (const events& other) const { if (t != other.t) { return t < other.t; } else return flag > other.flag; } }; events E[maxn]; int main() { #ifdef USACO ofstream fout ("milk2.out"); ifstream fin ("milk2.in"); #endif ///变量定义 while (cin >> N) { //读入事件 int j = 0; for (int i = 0; i < N; i++) { int t1, t2; cin >> t1 >> t2; E[j].t = t1; E[j].flag = true; j++; E[j].t = t2; E[j].flag = false; j++; } sort(E, E + j); //顺序扫描事件 int ansNoboby = 0, ansSomebody = 0, peopleCnts = 0; int startTime = E[0].t; for (int i = 0; i < j; i++) { if (!E[i].flag) { peopleCnts--; if (peopleCnts == 0) { ansSomebody = max(ansSomebody, E[i].t - startTime); startTime = E[i].t; } } else { peopleCnts++; if (peopleCnts == 1) { ansNoboby = max(ansNoboby, E[i].t - startTime); startTime = E[i].t; } } } cout << ansSomebody << " " << ansNoboby << endl; } ///结束 return 0; }