这是一道区间贪心问题中的区间选点问题, 即给定部分区间, 选得最少的点, 使得每个区间至少有一个点(含重叠)
应该来说有两种算法
一是左端点排序(<), 考虑右端点(<), 然后求交集的右边界, 没有交集就ans+1
//非洲的小孩 贪心
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(n));
typedef long long LL;
const LL maxn = 110;
struct node{
int b, e;
}t[maxn];
bool cmp(const node a, const node b)
{ //按开始时间升序排列, 如果相等按结束时间升序排列
if(a.b==b.b) return a.e < b.e;
return a.b < b.b;
}
int n;
int solve()
{
sort(t+1, t+1+n, cmp);
int ans = 1, range = t[1].e;
for(int i = 2; i <= n; i++){
if(t[i].b <= range) range = min(range, t[i].e);
else range = t[i].e, ans++;
}
return ans;
}
int main()
{
int h1,m1,h2,m2;
while(cin >> n){
ms(t, 0);
for(int i = 1; i <= n; i++){
scanf("%d:%d-%d:%d",&h1,&m1,&h2,&m2);
t[i].b = h1*60+m1, t[i].e = h2*60+m2; //转化成分钟制
if(t[i].b > t[i].e){ //考虑H1H1:M1M1晚于H2H2:M2M2的特殊情况
swap(t[i].b, t[i].e);
}
}
cout << solve() << endl;
}
return 0;
}
一种是右端点排序(<), 考虑左端点(>), 然后如果有交集就选可选区间的最后一个点, 没有交集就ans++
//非洲的小孩 贪心
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(n));
typedef long long LL;
const LL maxn = 110;
struct node{
int b, e;
}t[maxn];
bool cmp(const node a, const node b)
{ //按开始时间升序排列, 如果相等按结束时间升序排列
if(a.e==b.e) return a.b > b.b;
return a.e < b.e;
}
int n;
int solve()
{
sort(t+1, t+1+n, cmp);
/*int ans = 1, range = t[1].e;
for(int i = 2; i <= n; i++){
if(t[i].b <= range) range = min(range, t[i].e);
else range = t[i].e, ans++;
}*/
int ans = 0, cur = -10000;
for(int i = 1; i <= n; i++)
if(t[i].b > cur ) cur = t[i].e, ans++;
return ans;
}
int main()
{
int h1,m1,h2,m2;
while(cin >> n){
ms(t, 0);
for(int i = 1; i <= n; i++){
scanf("%d:%d-%d:%d",&h1,&m1,&h2,&m2);
t[i].b = h1*60+m1, t[i].e = h2*60+m2; //转化成分钟制
if(t[i].b > t[i].e){ //考虑H1H1:M1M1晚于H2H2:M2M2的特殊情况
swap(t[i].b, t[i].e);
}
}
cout << solve() << endl;
}
return 0;
}