题意:有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. 【BZOJ 2301】[HAOI2011]Problem b

    Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...

  2. storm sum aggregate 原语 聚合 本地测试

    编写storm程序,对数据进行聚合并且写入到mysql, 本文  主要说明数据中有多个字段需要进行sum或其他操作时的程序写法 1.主程序main方法,storm 拓扑运行入口 public clas ...

  3. linux复制多个文件到文件夹

    linux复制多个文件到文件夹 cp file1 file2 file3 directory即将文件file1 file2 file3复制到directory

  4. 【贪心】bzoj 3709:[PA2014]Bohater

    3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 653  Solved:  ...

  5. jquery捕捉文本域输入事件

    <input type='text' /> change事件是在文本域光标失去焦点时才会触发,要监听正在输入内容事件用键盘事件监听如果想要捕捉文本域输入事件,可以使用$("inp ...

  6. Windows平台上C++开发内存泄漏检查方法

    充分的利用调试工具可以非常方便地避免内存泄漏问题. 这里介绍两种方法,互为补充,第一种是VC编译器提供的方法,第二种是专用的内存泄漏检查工具Memmory Validator.这两种方法的基本原理是一 ...

  7. linux下mysql修改数据库账户root密码

    #先停止mysql,再运行下一句 $ mysqld_safe --user=mysql --skip-grant-tables --skip-networking & $ mysql -u r ...

  8. 苹果p12文件--一个苹果证书怎么多次使用(蛋疼,这些问题只有和其他企业合作才会遇到,别人的账号不可能给你,蛋疼....)

    在苹果开发者网站申请的证书,是授权mac设备的开发或者发布的证书,这意味着一个设备对应一个证书,但是99美元账号只允许生成3个发布证书,两个开发证书,这满足不了多mac设备的使用,使用p12文件可以解 ...

  9. vim查找/替换字符串 及一些高级用法

    例: 32 ./run 0_39.pkt 0_39.jpg 33 ./run 0_3.pkt 0_3.jpg 34 ./run 0_40.pkt 0_40.jpg 35 ./run 0_41.pkt ...

  10. Struts 2 + Spring2.5 + Hibernate3整合例子

    一.效果 1. 2. 二.结构 1. 2.用到jar包 antlr-2.7.6.jaraspectjrt.jaraspectjweaver.jarc3p0-0.9.1.jarcglib-nodep-2 ...