zoukankan      html  css  js  c++  java
  • CF GYM 100703I Endeavor for perfection

    题意:有n个学习领域,每个领域有m个课程,学习第i个领域的第j个课程可以获得sij个技能点,在每个领域中选择一个课程,要求获得的n个技能点的最大值减最小值最小,输出符合要求的策略。

    解法:尺取法。将课程的技能点按值进行排序,同时要记录每个值对应的领域,用尺取法选择第一段包含全部领域的区间,区间的边界即为最值,然后将左指针逐步右移,直到出现有的领域没有选课,继续右移右指针,直到结束。当右指针已移到最右的时候需要特判,只移动左指针。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int c[205];
    struct node
    {
        int a, b, c;
        bool operator < (const node &tmp) const
        {
            if(a == tmp.a)
                return b < tmp.b;
            return a < tmp.a;
        }
        bool operator == (const node &tmp) const
        {
            return a == tmp.a && b == tmp.b;
        }
        node(int a, int b, int c) : a(a), b(b), c(c){}
        node() {}
    };
    vector <node> v;
    int n;
    bool judge(int cnt[])
    {
        for(int i = 0; i < n; i++)
            if(!cnt[i])
                return false;
        return true;
    }
    int main()
    {
        while(~scanf("%d", &n))
        {
            v.clear();
            for(int i = 0; i < n; i++)
            {
                scanf("%d", &c[i]);
            }
            if(n == 1 && c[0] == 1) //需要特判否则RE
            {
                int x;
                scanf("%d", &x);
                printf("0
    1
    ");
                continue;
            }
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < c[i]; j++)
                {
                    int s;
                    scanf("%d", &s);
                    v.push_back(node(s, i, j + 1));
                }
            }
            sort(v.begin(), v.end());
            v.erase(unique(v.begin(), v.end()), v.end());
            int len = v.size();
            int flag = 0;
            int now = -1;
            int cnt[205] = {0};
            int l = 0, r = 0;
            cnt[v[0].b] = 1;
            int ans = INT_MAX, pl, pr;
            for(; l < len;)
            {
                if(!flag)
                {
                    r++;
                    cnt[v[r].b]++;
                    if(judge(cnt))
                    {
                        flag = 1;
                        if(v[r].a - v[l].a < ans)
                        {
                            ans = v[r].a - v[l].a;
                            pl = l, pr = r;
                        }
                        continue;
                    }
                }
                else 
                {
                    if(~now && r < len - 1)
                    {
                        r++;
                        cnt[v[r].b]++;
                        if(cnt[now])
                        {
                            now = -1;
                            if(v[r].a - v[l].a < ans)
                            {
                                ans = v[r].a - v[l].a;
                                pl = l, pr = r;
                            }
                        }
                    }
                    else
                    {
                        if(r == len - 1)
                        {
                            cnt[v[l].b]--;
                            l++;
                            if(judge(cnt))
                            {
                                if(v[r].a - v[l].a < ans)
                                {
                                    ans = v[r].a - v[l].a;
                                    pl = l, pr = r;
                                }
                            }
                            continue;
                        }
                        cnt[v[l].b]--;
                        if(!cnt[v[l].b])
                        {
                            now = v[l].b;
                            l++;
                        }
                        else
                        {
                            l++;
                            if(v[r].a - v[l].a < ans)
                            {
                                ans = v[r].a - v[l].a;
                                pl = l, pr = r;
                            }
                        }
                    }
                }
            }
            printf("%d
    ", ans);
            int prt[205];
            for(int i = pl; i <= pr; i++)
            {
                prt[v[i].b] = v[i].c;
            }
            for(int i = 0; i < n; i++)
            {
                if(i)
                    printf(" ");
                printf("%d", prt[i]);
            }
            puts("");
        }
        return 0;
    }
    

      

  • 相关阅读:
    poj 1860 Currency Exchange(最短路径的应用)
    poj 2965 The Pilots Brothers' refrigerator
    zoj 1827 the game of 31 (有限制的博弈论)
    poj 3295 Tautology (构造法)
    poj 1753 Flip Game(枚举)
    poj 2109 (贪心)
    poj 1328(贪心)
    Qt 对单个控件美化
    Qt 4基础
    Bash Shell
  • 原文地址:https://www.cnblogs.com/Apro/p/4685296.html
Copyright © 2011-2022 走看看