zoukankan      html  css  js  c++  java
  • 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;
    }

      

  • 相关阅读:
    第十一周作业
    第十周作业
    第九周编程
    第十二周作业
    第十一周作业
    第十周作业
    第八周作业
    第七周作业
    第五周作业
    2019春季学期第四周作业
  • 原文地址:https://www.cnblogs.com/jifahu/p/5988611.html
Copyright © 2011-2022 走看看