解题思路:
严格按照题目的要求来做,读题后把关键信息记录在草稿纸上。题目要求根据三个方面进行筛选:节点亲和性,任务亲和性,任务反亲和性。
- 计算节点亲和性
计算任务必须在指定可用区上运行。
- 计算任务亲和性
计算任务必须和指定应用的计算任务在同一可用区上运行。
- 计算任务反亲和性
计算任务不能和指定应用的计算任务在同一个计算节点上运行。
不难发现3个要求中的高频词汇:指定应用。我们可以将所有应用信息(运行节点,运行区域)以结构体的方式储存在动态数组vector里(结构体内部还要定义集合set)来完成筛选和安排时的信息检索与存入,但是根据输入规则,应用数量上限为10^9,数量级太大,相应的检索与存入耗时较大,因此必须转换思路。我最后采用的是定义结构体AREA,储存可用区内部的节点编号和应用编号;定义结构体CPU,储存节点的编号,所属可用区编号和任务数量,代码如下
struct AREA
{
set<int> clist;
set<int> appl;
};
struct CPU
{
int cid;
int aid;
int tasks;
set<int> appl;
};
查看输入格式和样例,用输入格式的名字为变量命名,按照题目的要求筛选节点
cin >> f >> a >> na >> pa >> paa >> paar;
vector<int> cpul;
if(na == 0)
{
for(int i = 0; i < point_num; i++)
{
int aid = point_info[i].aid;
if(pa != 0 && area[aid].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[i].appl.count(paa)==1)
continue;
cpul.push_back(i);
}
}
else
{
for(auto it = area[na].clist.begin(); it != area[na].clist.end(); it++)
{
if(pa != 0 && area[na].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[*it].appl.count(paa)==1)
continue;
cpul.push_back(*it);
}
}
if(cpul.size() == 0)
{
if(na == 0)
{
for(int i = 0; i < point_num; i++)
{
int aid = point_info[i].aid;
if(pa != 0 && area[aid].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[i].appl.count(paa)==1 && paar == 1)
continue;
cpul.push_back(i);
}
}
else
{
for(auto it = area[na].clist.begin(); it != area[na].clist.end(); it++)
{
//int aid = point_info[*it].aid; 无效语句,增加工作量
if(pa != 0 && area[na].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[*it].appl.count(paa)==1 && paar == 1)
continue;
cpul.push_back(*it);
}
}
}
编写比较函数对可用节点列表进行排序
bool comp(int c1, int c2)
{
if(cpu_info[c1].tasks == cpu_info[c2].tasks)
return (c1 < c2);
return (cpu_info[c1].tasks < cpu_info[c2].tasks);
}
然后在排序前,需要特殊处理找不到节点的情况,因为空数组不需要排序,并且C++的STL容器和C语言的数组在用指针调用的时候都不会检查指针的合法性,如果数组为空,编译能通过但是运行到调用指针的那一行就会崩溃。
sort(cpul.begin(), cpul.end(), comp); //会崩溃
if(cpul.size() == 0) //正确代码
printf("%d ", 0);
else
sort(cpul.begin(), cpul.end(), comp);
满分代码
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
struct AREA
{
set<int> clist;
set<int> appl;
};
struct CPU
{
int cid;
int aid;
int tasks;
set<int> appl;
};
int point_num, area_num;
CPU *cpu_info; //设置指针类型,方便函数调用
bool comp(int c1, int c2) //比较参数
{
if(cpu_info[c1].tasks == cpu_info[c2].tasks)
return (c1 < c2);
return (cpu_info[c1].tasks < cpu_info[c2].tasks);
}
int main()
{
scanf("%d %d", &point_num, &area_num);
AREA area[area_num+1];
CPU point_info[point_num];
cpu_info = point_info;
for(int i = 0; i < point_num; i++)
{
int father_area;
scanf("%d", &father_area);
point_info[i].aid = father_area;
point_info[i].cid = i;
point_info[i].tasks = 0; //这里的初始化很重要,不然后面在比较的时候会报错
area[father_area].clist.insert(i);
}
int group_num;
scanf("%d", &group_num); //压缩任务条数
for(int num = 0; num < group_num; num++)
{
int times = 0;
int f,a, na, pa, paa, paar;
cin >> f >> a >> na >> pa >> paa >> paar;
vector<int> cpul;
start:
if(na == 0)
{
for(int i = 0; i < point_num; i++)
{
int aid = point_info[i].aid;
if(pa != 0 && area[aid].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[i].appl.count(paa)==1)
continue;
cpul.push_back(i);
}
}
else
{
for(auto it = area[na].clist.begin(); it != area[na].clist.end(); it++)
{
if(pa != 0 && area[na].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[*it].appl.count(paa)==1)
continue;
cpul.push_back(*it);
}
}
if(cpul.size() == 0)
{
if(na == 0)
{
for(int i = 0; i < point_num; i++)
{
int aid = point_info[i].aid;
if(pa != 0 && area[aid].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[i].appl.count(paa)==1 && paar == 1)
continue;
cpul.push_back(i);
}
}
else
{
for(auto it = area[na].clist.begin(); it != area[na].clist.end(); it++)
{
if(pa != 0 && area[na].appl.count(pa)==0)
continue;
if(paa != 0 && point_info[*it].appl.count(paa)==1 && paar == 1)
continue;
cpul.push_back(*it);
}
}
}
if(times < f)
{
if(cpul.size() == 0) //指针开始处不能为空,否则编译能过但是无法运行
printf("%d ", 0);
else
{
sort(cpul.begin(), cpul.end(), comp);
printf("%d ",*cpul.begin()+1);
point_info[*cpul.begin()].tasks += 1;
point_info[*cpul.begin()].appl.insert(a);
area[point_info[*cpul.begin()].aid].appl.insert(a);//此处需要重新筛选
}
times++;
cpul.clear();
goto start;
}
printf("\n");
}
return 0;
}