1.解题思路
直接暴力枚举,对一组任务数为f的输入可看作f次一组任务的输入,遍历所有计算节点,判断其是否满足节点亲和性、任务亲和性、任务反亲和性,满足则加入待选集合res,遍历完一轮后看res是否为空,若为空且paar=1直接输出0继续,paar=0则去掉反亲和性要求再遍历一遍,最后按节点上任务数,节点编号从小到大排序,算出最终放置的节点,并更新相应节点的任务数,节点上的应用集合以及该节点所属可用区的应用集合。
2.满分代码
#include<iostream>
#include<utility>
#include<unordered_map>
#include<algorithm>
#include<set>
using namespace std;
const int N=1010;
struct cnode{//计算节点
int area;//所属可用区
int cnt;//任务数
unordered_map<int,bool>app;//运行在该节点上的应用
}node[N];
unordered_map<int,set<int>>region;//可用区--运行在可用区上的应用
int n,m,g;
bool solve(cnode x,int na,int pa,int paa)//判断一个节点是否满足节点亲和性/任务亲和性/任务反亲和性
{
if((na!=0)&&(x.area!=na))return false;
if((pa!=0)&&(region[x.area].count(pa)==0))return false;
if((paa!=0)&&(x.app.count(paa)))return false;
return true;
}
bool cmp(int x,int y)
{
if(node[x].cnt!=node[y].cnt)
return node[x].cnt<node[y].cnt;
else
return x<y;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>node[i].area;
}
cin>>g;
while(g--)
{
int f,a,na,pa,paa,paar;
cin>>f>>a>>na>>pa>>paa>>paar;
for(int i=1;i<=f;i++)
{
vector<int>res;
for(int j=1;j<=n;j++)
{
if(solve(node[j],na,pa,paa))
res.push_back(j);
}
if(res.size()==0)
{
if(paar==1)
{
cout<<0<<" ";
continue;
}
else
for(int j=1;j<=n;j++)
{
if(solve(node[j],na,pa,0))
res.push_back(j);
}
if(res.size()==0)
{
cout<<0<<" ";
continue;
}
}
sort(res.begin(),res.end(),cmp);
cout<<res[0]<<" ";
node[res[0]].cnt++;
node[res[0]].app[a]=true;
region[node[res[0]].area].insert(a);
}
cout<<endl;
}
return 0;
}