ZOJ3953-Intervals-贪心

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

Catalog

Problem:Portal传送门

 原题目描述在最下面。
 给你n个区间,问最少删除多少个区间,使得任意三个区间不两两相交。

Solution:

 先把所有区间按先左端点再右端点从小到大排序,每次选出前面相邻的三个区间:
 如果两两相交则一定要删除右端点最大的那个区间,因为这个区间的能影响的范围更大!
 若不两两相交就放掉右端点最小的,用下一个区间代替它,因为左端点是递增的,任选后面两个区间肯定不会和这个右端点最小的区间两两相交!重复这个过程。

 还有就是最开始区间一定要先按左端点再按右端点排序。
 我提供一组样例:

4
2 5
3 7
1 15
9 12


AC_Code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<vector>
#include<cmath>
#include<bitset>
#include<cassert>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef pair<int,int> pii;
typedef long long LL;
const int MXN = 60000 + 7;
const int MXE = 1e6 + 7;
const int mod = 998244353;
const int INF = 0x3f3f3f3f;

int n, m;
struct lp{
    int l, r, id;
}cw[MXN],op[3];
bool cmp1(lp &a,lp &b){
    if(a.r!=b.r)return a.r < b.r;
    return a.l < b.l;
}
bool cmp2(lp &a,lp &b){
    if(a.l!=b.l)return a.l < b.l;
    return a.r < b.r;
}
int main(){
    int tim;
    scanf("%d", &tim);
    while(tim--){
        scanf("%d", &n);
        for(int i = 0; i < n; ++i){
            scanf("%d%d", &cw[i].l, &cw[i].r);cw[i].id = i+1;
        }
        if(n<2){
            printf("0\n\n");
            continue;
        }
        sort(cw,cw+n,cmp2);
        op[0] = cw[0]; op[1] = cw[1];
        int cnt = 0;
        std::vector<int> ans;
        for(int t = 2; t < n; ++t){
            op[2] = cw[t];
            sort(op,op+3,cmp1);
            int flag = 1;
            for(int i = 0; i < 3; ++i){
                for(int j = i + 1; j < 3; ++j){
                    if(op[j].l>op[i].r)flag = 0;
                }
            }
            if(flag == 0){
                op[0] = op[1];
                op[1] = op[2];
            }else{
                cnt++;
                ans.push_back(op[2].id);
            }
        }
        printf("%d\n", cnt);
        if(cnt == 0)printf("\n");
        else {
            sort(ans.begin(),ans.end());
            for(int i = 0; i < cnt; ++i){
                printf("%d%c", ans[i], " \n"[i==cnt-1]);
            }
        }
    }
    return 0;
}


Problem Description:

这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值