UVALive 6911 Double Swords (Set,贪心,求区间交集)

  补:华中VJ这个题目很多标程都不能AC了,包括我下面原本AC了的代码,再交就WA掉了,感觉是样例有问题呢……

  首先左边的是必须要选的,然后右边的需要注意,有些区间是可以舍掉的。1、区间里有两个不同的A。 2、区间里有一个A,而且这个A不是这个区间对应的A。

  这个题我一开始错在了第2个判定条件上,我定义的id记录的是最后一个出现位置,不能进行判断,所以干脆在结构体里记录了他对应的A值。

  舍掉后留下的区间,可以按照区间左边界排序,然后求交集即可。

  总体来说,贪心的思想还是不难的,就是有一些细节需要注意。

  代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int N = 1e5+5;
const int M = 1e6+6;
set<int>st;
set<int>:: iterator it;
map<int,int> id;
struct Edge {
    int l,r,A,ok;
    void Set(int x,int y,int a) {
        l = x;
        r = y;
        A = a;
        ok = 0;
    }
} e[N];
int sum[M];
bool cmp(Edge a,Edge b) {
    if(a.l != b.l) return a.l < b.l;
    return a.r < b.r;
}
int main() {
//    freopen("F.in.cpp","r",stdin);
    int T,n,a,b,c,ans,ca=0,Max,Min,cnt;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        st.clear();
        id.clear();
        Max = -1;
        Min = 1e8;
        for(int i = 1; i <= n; i++) {
            scanf("%d%d%d",&a,&b,&c);
            id[a] = i;
            e[i].Set(b,c,a);
            st.insert(a);
            Max = max(max(Max,a),e[i].r);
            Min = min(min(Min,a),e[i].l);
        }
        cnt = 0;
        for(int i = Min-1; i <= Max; i++) {
            if(id[i]) cnt++;
            sum[i] = cnt;
        }
        ans = st.size();
//        printf("ans1 = %d
",ans);
        for(int i = 1; i <= n; i++) {
            if(sum[e[i].r] - sum[e[i].l-1] == 1) {
                it = st.lower_bound(e[i].l);
                if(*it != e[i].A) e[i].ok = 1;
            }
            if(sum[e[i].r] - sum[e[i].l-1] > 1) e[i].ok = 1;
        }
        sort(e+1,e+n+1,cmp);
        int tr=-1;
        for(int i = 1; i <= n; i++) {
            if(e[i].ok == 1) continue;
            if(tr == -1 || tr < e[i].l) {
                tr = e[i].r;
                ans++;
            } else if(tr >= e[i].l) {
                tr = min(e[i].r,tr);
            }
        }
        printf("Case #%d: %d
",++ca,ans);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/jifahu/p/5988611.html