题意:有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;
}

  

CF GYM 100703I Endeavor for perfection的更多相关文章

  1. CF Gym 102028G Shortest Paths on Random Forests

    CF Gym 102028G Shortest Paths on Random Forests 抄题解×1 蒯板子真jir舒服. 构造生成函数,\(F(n)\)表示\(n\)个点的森林数量(本题都用E ...

  2. CF gym 101933 K King's Colors —— 二项式反演

    题目:http://codeforces.com/gym/101933/problem/K 其实每个点的颜色只要和父亲不一样即可: 所以至多 i 种颜色就是 \( i * (i-1)^{n-1} \) ...

  3. cf Gym 101086M ACPC Headquarters : AASTMT (Stairway to Heaven)

    题目: Description standard input/output As most of you know, the Arab Academy for Science and Technolo ...

  4. CF Gym 100685A Ariel

    传送门 A. Ariel time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  5. CF Gym 100685E Epic Fail of a Genie

    传送门 E. Epic Fail of a Genie time limit per test 0.5 seconds memory limit per test 64 megabytes input ...

  6. CF GYM 100703A Tea-drinking

    题意:龙要制作n个茶,每个茶的配方是一个字符串,两个字符串之间有一个差值,这个差值为两个字符串每个对应字母之间差的绝对值的最大值,求制作所有茶时获得的所有差值中的最大值. 解法:克鲁斯卡尔.将茶的配方 ...

  7. CF GYM 100703B Energy Saving

    题意:王子每月买m个灯泡给n个房间换灯泡,如果当前有的灯泡数够列表的第一个房间换的就全换,直到灯泡不够为止,给出q个查询,查询x月已经换好几个房子,手里还剩多少灯泡. 解法:水题……小模拟. 代码: ...

  8. CF GYM 100703F Game of words

    题意:两个人玩n个游戏,给出每人玩每个游戏的时间,两个人需要在n个游戏中挑m个轮流玩,求最短时间. 解法:dp.(这场dp真多啊……话说也可以用最小费用最大流做……然而并不会XD)dp[i][j][k ...

  9. CF GYM 100703G Game of numbers

    题意:给n个数,一开始基数为0,用这n个数依次对基数做加法或减法,使基数不超过k且不小于0,输出最远能运算到的数字个数,输出策略. 解法:dp.dp[i][j]表示做完第i个数字的运算后结果为j的可能 ...

随机推荐

  1. iOS百度地图路径规划和POI检索详细总结-b

    路径规划.png 百度地图的使用 百度地图API的导入网上说了许多坑,不过我遇到的比较少,这里就放两个比较常见的吧.坑一: 奥联WIFI_xcodeproj.png 如上图所示,在infoplist里 ...

  2. 2336: [HNOI2011]任务调度 - BZOJ

    一道随机算法的题目 随便用什么随机算法 首先我们可以想到枚举类型3的最终类型,然后再做 先贪心出一个较优的序列,首先我们知道肯定是在A机器上先做完类型1的事件再做类型2的事件,机器B也类似,因为这些没 ...

  3. 内存泄露 memory leak 的原因

    #include <iostream> using namespace std; void foo() { MyClass *x; x = new MyClass(); //指向的丢失了 ...

  4. css3分栏

    <!DOCTYPE HTML> <meta charset="UTF-8"> <title>分栏</title> <style ...

  5. 现在不使用ZeroClipboard我们也能实现复制功能(转)

    现在不使用ZeroClipboard我们也能实现 首先,我们保证页面结构不变,但不在引入ZeroClipboard插件: 1 <input type="text" name= ...

  6. js常识

    btnDelAll.Attributes.Add("onclick", "<script lunguage='javascript'>return windo ...

  7. Extjs 4 chart自定义坐标轴刻度

    Sencha出品的ExtJs是一个非常优秀的前端框架,尤其是具有里程碑意义的4.0的发布.4.0采用MVC架构和全新的class系统,并且提供了非常丰富的组件.但是,尽管ExtJS如此强大,仍有不尽人 ...

  8. Hadoop分布式文件系统(HDFS)详解

    HDFS简介: 当数据集的大小超过一台独立物理计算机的存储能力时,就有必要对它进行分区 (partition)并存储到若干台单独的计算机上.管理网络中跨多台计算机存储的文件系统成为分布式文件系统 (D ...

  9. P51、面试题5:从尾到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 链表结点定义如下: Struct ListNode{ int   m_nKey; ListNode*   m_pNext; }; 我们可 ...

  10. python 简单示例说明os.walk和os.path.walk的不同

    import os,os.path def func(arg,dirname,names): for filespath in names: print os.path.join(dirname,fi ...