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\n1\n");
            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\n", 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;
}

  

posted @ 2015-07-29 10:51  露儿大人  阅读(302)  评论(0编辑  收藏  举报