计算资源调度器 | |
时间限制: | 1.0s |
内存限制: | 512.0MB |
问题描述: | 题目背景西西艾弗岛上兴建了一批数据中心,建设了云计算资源平台。小 C 是主管西西艾弗云开发的工程师。西西艾弗云中有大量的计算节点,每个计算节点都有唯一编号。 西西艾弗云中运行的计算任务分为不同的应用,每个计算任务都有一个应用与之对应,一个应用中可能包括多个计算任务。 下图示意性地说明了可用区、计算节点、计算任务之间的关系,同时也说明了应用和计算任务的对应关系。 一开始,小 C 使用了电子表格程序来统计计算任务的分配情况。随着云上的计算节点和计算任务的不断增多,小 C 被这些奇怪的要求搞得焦头烂额,有的时候还弄错了安排,让客户很不满意。 问题描述计算任务对计算节点的要求十分复杂而且又不好描述,你对小 C 表示写程序这件事很为难。于是,小 C 进行了调研,
小 C 要求你按照如下方法来分配计算节点:按照计算任务的启动顺序,根据要求,依次为每个计算任务选择计算节点。一旦选择了一个计算节点,就固定下来不再变动,
输入格式输入的第一行包含两个由空格分隔的正整数 |
和 ,分别表示计算节点的数目和可用区的数目。计算节点从 到 编号,可用区从 到
编号;
输入的第二行包含
个由空格分隔的正整数 ,表示编号为 的计算节点位于编号为 的可用区。其中,
;
输入的第三行包含一个正整数
,表示计算任务的组数;
接下来的
行,每行包含六个由空格分隔的整数 、、、、、
,表示依次启动的一组计算任务的信息,其中:
:表示要接连启动 个所属应用和要求相同的计算任务,其中
- ;
- :表示这 个计算任务所属应用的编号,其中 (
- 代表最大应用编号);
- :表示计算节点亲和性要求,其中 。当 时,表示没有计算节点亲和性要求;否则表示要运行在编号为
- 的可用区内的计算节点上;
- :表示计算任务亲和性要求,其中 。当 时,表示没有计算任务亲和性要求;否则表示必须和编号为
- 的应用的计算任务在同一个可用区运行;
- :表示计算任务反亲和性要求,其中 。当 时,表示没有计算任务反亲和性要求;否则表示不能和编号为
- 的应用的计算任务在同一个计算节点上运行;
- :表示计算任务亲和性要求是必须满足还是尽量满足,当 时, 也一定为 0;否则 表示“必须满足”,
- 表示“尽量满足”。
计算任务按组输入实际上是一种简化的记法,启动一组
和连续启动 组并无不同。
输出格式
输出
行,每行有个整数,由空格分隔,分别表示每个计算任务被分配的计算节点的情况。若该计算任务没有被分配,则输出 0;否则输出被分配的计算节点的编号。
样例输入
10 4 1 1 1 1 1 2 2 2 2 2 6 2 1 4 1 2 1 6 1 1 0 1 1 1 2 2 0 0 0 6 1 2 0 2 1 5 2 2 0 1 0 11 3 0 1 3 0
Data
样例输出
0 0 1 2 3 4 5 0 6 7 8 9 10 7 8 6 6 6 6 6 1 2 3 4 5 9 10 7 8 6 1
Data
样例解释
本输入中声明了十个计算节点,前五个位于可用区 1,后五个位于可用区 2。可用区 3 和 4 不包含任何计算节点。
对于第一组计算任务,由于它们声明了计算节点亲和性要求,但要求的可用区编号是 4,该可用区不包含计算节点,因此都不能满足。
对于第二组计算任务,要在可用区 1 中启动 6 份应用 1 的任务,并且要求了计算任务反亲和性。因此,前五份任务分别被安排在前五个节点上。对于第六份任务,由于它必须运行于可用区 1,所以能够安排的范围仅限于前五个节点。但是它还指定了强制的计算任务反亲和性,前五个节点上已经启动了属于应用 1 的计算任务,因此没有能够运行它的节点。
对于第三组计算任务,要在可用区 2 中启动 1 份应用 2 的任务,直接将其分配给节点 6。
对于第四组计算任务,要在可用区 2 中启动 6 份应用 1 的任务,并且要求了计算任务反亲和性,不能和应用 2 的计算任务分配在同一个节点上。因此,节点 6 不能用于分配,这六份任务只能分配在节点 7~10 上。按照题意,选取运行任务数最少的和编号最小的,因此依次分配 7、8、9、10、7、8。
对于第五组计算任务,要在可用区 2 中启动 5 份应用 2 的任务,并且要求了尽量满足的计算任务反亲和性,不能和应用 1 的计算任务分配在同一个节点上。此时,可用区 2 中的节点 6 上没有应用 1 的计算任务,因此这 5 份计算任务都会被分配到这个节点上。
对于第六组计算任务,要启动 11 份应用 3 的任务,并且要求了尽量满足的计算任务反亲和性,不能和应用 3 的其它计算任务分配在同一个节点上,同时要求和应用 1 的计算任务位于同一个可用区。应用 1 位于两个可用区,因此全部 10 个节点都可以用于分配。对于前 10 份任务,按照题意,依次选取运行的任务数最少且编号最小的节点进行分配。对于第 11 份任务,由于所有的节点上都运行有应用 3 的任务,因此没有节点符合它的反亲和性要求。又因为反亲和性要求是尽量满足的,因此可以忽略这一要求,将它安排在节点 1 上。
#include <bits/stdc++.h> using namespace std; struct node { int idx; int num; int belong; set<int> yy; } nodes[1050]; map<int, int> region[1050]; int cnt[1050]; int n, m, l, f, a, na, pa, paa, paar, g; void judge1(int na) { if (na == 0) { for (int i = 1; i <= n; ++i) cnt[i]++; } else { for (int i = 1; i <= n; ++i) { if (nodes[i].belong == na) cnt[i]++; } } } void judge2(int pa) { if (pa == 0) { for (int i = 1; i <= n; ++i) cnt[i]++; } else { for (int i = 1; i <= n; ++i) { if (region[nodes[i].belong][pa] == 1) cnt[i]++; } } } void judge3(int paa) { if (paa == 0) { for (int i = 1; i <= n; ++i) cnt[i]++; } else { for (int i = 1; i <= n; ++i) { if (nodes[i].yy.count(paa) == 0) cnt[i]++; } } } int get_min(vector<node> group) { int min_cur = group[0].idx; int i; int len = group.size(); for (i = 1; i < len; ++i) { if (nodes[min_cur].num > group[i].num) min_cur = group[i].idx; else if (nodes[min_cur].num == group[i].num && nodes[min_cur].idx > group[i].idx) min_cur = group[i].idx; } return min_cur; } void work(int a, int na, int pa, int paa, int paar) { memset(cnt, 0, sizeof(cnt)); judge1(na); judge2(pa); judge3(paa); vector<node> group; for (int i = 1; i <= n; ++i) { if (cnt[i] == 3) group.push_back(nodes[i]); } if (group.size()) { int cur = get_min(group); cout << cur << " "; nodes[cur].yy.insert(a); nodes[cur].num++; region[nodes[cur].belong][a] = 1; return; } else if (!group.size() && paa && !paar) { memset(cnt, 0, sizeof(cnt)); judge1(na); judge2(pa); vector<node> group; for (int i = 1; i <= n; ++i) { if (cnt[i] == 2) group.push_back(nodes[i]); } if (group.size()) { int cur = get_min(group); cout << cur << " "; nodes[cur].yy.insert(a); nodes[cur].num++; region[nodes[cur].belong][a] = 1; return; } } cout << 0 << " "; } int main() { cin >> n >> m; for (int i = 1; i <= n; ++i) { cin >> l; nodes[i].idx = i; nodes[i].belong = l; } cin >> g; while (g--) { cin >> f >> a >> na >> pa >> paa >> paar; while (f--) { work(a, na, pa, paa, paar); } cout << endl; } }