第三题就有一点难度了,题干也比较长
这道题用到了大量的stl,stl的具体操作请上网学习,或者评论区问我都可以。
#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<queue>
#include<vector>
using namespace std;
int n,m,g;
typedef struct Node
{
int id;
int cnt;
int pos;//节点所在可用区的编号
map<int,bool> book; //节点运行了什么任务
bool operator < (const Node &a)const
{ //重载运算符,先比较cnt再比较id
if(cnt!=a.cnt)
return cnt>a.cnt;
else
return id>a.id;
}
}Node;
Node node[1010];
map <int,bool> qu[1010];//每个可用区执行了什么任务
priority_queue <Node> choose(int &a,int &na,int &pa,int paa,int &paar)
{
//过滤节点亲和性
vector<Node> aa;
if(na)
{
for(int i=1; i<=n; i++)
{
if(node[i].pos==na)//如果可以满足,我们就把它添加到堆中
aa.push_back(node[i]);
}
}
else//如果na的值为0,则说明亲和性无要求,我们也把它加入进去
{
for(int i=1; i<=n; i++)
aa.push_back(node[i]);
}
//过滤任务亲和性
vector<Node> b;
if(pa)//如果任务亲和性要求不为0,则我们过滤
{
for(int i=0; i<aa.size(); i++)
{
if(qu[aa[i].pos][pa])//如果这个地方有它需要一起的任务,则符合要求
b.push_back(node[i]);
}
}
else//如果没有任务亲和性,则我们不需要筛选了,直接把刚才筛选好的aa容器赋值给b
b=aa;
//过滤任务反亲和性
vector<Node> c;
if(paa)//如果有反亲和性要求,我们就去筛选
{
for(int i=0; i<b.size(); i++)
{
if(!b[i].book[paa])//如果当前节点没有任务,则符合要求
c.push_back(b[i]);
}
}
else c=b;//否则不筛
priority_queue<Node> res;//建一个堆,进行排序
for(int i=0; i<c.size(); i++)
res.push(c[i]);
return res;//返回堆
}
int ans(int tf,priority_queue<Node> &res,int &a,int paa)
{
while(tf && !res.empty())//如果任务分配完了或者节点分配完了就停止循环
{
Node temp=res.top();
res.pop();
cout<<temp.id<<' ';
node[temp.id].cnt++;
node[temp.id].book[a]=true;//这个节点已经有任务了
qu[temp.pos][a]=true;//如果反亲和性是它自己,则这个节点不可用了。否则还要把这个节点入堆
if(a!=paa) temp.cnt++,res.push(temp);
tf--;
}
return tf;//返回剩余的任务数
}
int main()
{
cin>>n>>m;
int temp;
for(int i=1; i<=n; i++)
{
node[i].id=i;
cin>>temp;
node[i].pos=temp;
}
cin>>g;
int f,a,na,pa,paa,paar;
while(g--)
{
cin>>f>>a>>na>>pa>>paa>>paar;
priority_queue <Node> heap=choose(a,na,pa,paa,paar);//每输入一次数据,就筛选一遍,建立一个符合条件的堆(排序)
int tf=ans(f,heap,a,paa);//打印答案
if(tf && !paar)//如果有没分配的,则再筛选一遍
{
heap=choose(a,na,pa,0,paar);
tf=ans(tf,heap,a,0);
}
while(tf--)//剩余的任务都是无法满足的,则输出0
cout<<"0 ";
cout<<endl;
}
return 0;
}
以上即为代码和解析
欢迎评论区探讨