1. 程式人生 > >nyoj 1036-非洲小孩 (區間貪心)

nyoj 1036-非洲小孩 (區間貪心)

這是一道區間貪心問題中的區間選點問題, 即給定部分割槽間, 選得最少的點, 使得每個區間至少有一個點(含重疊)

應該來說有兩種演算法

一是左端點排序(<), 考慮右端點(<), 然後求交集的右邊界, 沒有交集就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;
}