首页 > 其他分享 >CSP202203_3

CSP202203_3

时间:2022-09-27 19:12:41浏览次数:57  
标签:node map CSP202203 int read vec 节点

CSP202203_3

目录

题目

计算资源调度器

思路

直接模拟,画个大致的分析图即可理清题目要求。

一个区上有多个节点,一个应用有多个任务。

一个任务只占用一个节点,多个任务可在一个节点上进行。

三种要求:

  1. 任务\(\in\)区
  2. 任务\(\in\)区 && 区上有特定应用的任务
  3. 任务\(\notin\) 节点 && 节点上有特定应用的任务

确定一系列任务,选择其最佳运行的节点。

确定维护的一定是节点的信息(因为所有操作都在节点上进行)。

考虑节点本身,首先应记录其自身编号,所属的区。

基于上述三种要求以及选择标准,我们还要记录节点运行任务总数、节点的所有任务所属应用。

使用 unordered_map 记录每个节点(具体原因后述)。

总体上就是分别针对三种需求,在所有节点中依次剔除不符合要求的节点,最后根据标准进行排序及选择。

一些问题

  • 关于unordered_map:一开始直接采用的 map 维护,但结果是75pts(TLE),借鉴了其他人写这道题的方法,使用 unordered_map 即可AC。

    unordered_map因为不要求有序,因此使用哈希表维护,而map使用的是红黑树,显然数据量与操作很多时,unordered_map要快上不少

  • 最后的排序问题,通过自定义比较函数,只能拿到80pts(TLE),而类似处理中,他人博客通过重载运算符,使用 lambda 语句作为比较函数,则可AC。具体原因不太确定,感觉可能是涉及到STL的一些底层实现?望dalao指点

  • 关于迭代器的删除操作:vector 等序列性容器与 map 等关联性容器在删除迭代器指向内容后迭代器的变化是不同的,这次一定记住

  • 在最初模拟时,样例最后一个点总是错误,最终确定是在第三个要求的函数实现错误:

    函数参数传递的只是vec而不是其引用。如果传引用,在进行第三步判断时,可能会导致vec1变空。

    但实际若vec2由于非必须要求而可以不为空,所供选择的节点为为进行第三步判断的vec1,此处就会产生错误,将任务误判为无节点可用。

Code

80pts(直接按注释替换sort的比较部分即可AC)

#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || ch >'9')
	{
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9')
	{
		x = (x<<1) + (x<<3) + (ch^48);
		ch = getchar();
	}
	return x*f;
}

struct NODE
{
	int id; //编号
	int area; //所属区
	int cnt; //运行任务数量
	set <int> num; //运行任务所属应用的编号
	// bool operator <(const NODE& a)const{
	// 	if(this->cnt != a.cnt){
	// 		return this->cnt < a.cnt;
	// 	}
	// 	else {
	// 		return this->id < a.id;
	// 	}
	// }
};

int t, m;

vector <int> all;

unordered_map <int, NODE> node;

void Fun_1(int n, vector <int> &vec) //删除不满足节点亲和性的节点
{
	//cout << "Fun1 Begin" << endl;
	vector <int> :: iterator it = vec.begin();
	while(it != vec.end())
	{
		if(node[*it].area != n)
		{
			it = vec.erase(it);
		}
		else it++;
	}
	return;
}

void Fun_2(int n, vector <int> &vec) //与编号为n的应用的任务在同一区
{
	//cout << "Fun2 Begin" << endl;
	set <int> mry; //记录可行的区
	for(int i = 1; i <= node.size(); i++)
	{
		if(node[i].num.count(n))
		{
			mry.insert(node[i].area);
		}
	}
	vector <int> :: iterator it = vec.begin();
	while(it != vec.end())
	{
		if(!mry.count(node[*it].area))
		{
			it = vec.erase(it);
		}
		else it++;
	}
	return;
}

vector <int> Fun_3(int n, vector <int> vec)
{
	//cout << "Fun3 Begin" << endl;
	vector <int> :: iterator it = vec.begin();

	while(it != vec.end())
	{
		if(node[*it].num.count(n))
		{
			it = vec.erase(it);
		}
		else it++;
	}
	return vec;
}

bool cmp(int a, int b)
{
	if(node[a].cnt != node[b].cnt) return node[a].cnt < node[b].cnt;
	else return node[a].id < node[b].id;
}

int main()
{
	t = read(), m = read();
	for(int i = 1; i <= t; i++)
	{
		int a = read();
		node.insert(make_pair(i, NODE{i, a, 0, set<int>()}));
		all.push_back(i);
		//< 编号, {} >
	}
	int g = read();
	while(g--)
	{
		int f = read(), a = read(), na = read();
		int pa = read(), paa = read(), paar = read();
		while(f--)
		{
			vector <int> vec1 = all, vec2;
			if(na)
			{
				Fun_1(na, vec1);
			}
			if(pa)
			{
				Fun_2(pa, vec1);
			}
			if(paa)
			{
				vec2 = Fun_3(paa, vec1);
			}
			if(vec1.empty())
			{
				cout << 0 << " ";
				continue;
			}
			if(vec2.empty())
			{
				if(paar)
				{
					cout << 0 << " ";
					continue;
				}
				else
				{
					vec2 = vec1;
				}
			}
			sort(vec2.begin(), vec2.end(), cmp);
			// sort(vec2.begin(), vec2.end(), [](const auto& a, const auto& b)->bool{
			// 	return node[a] < node[b];
			// 	});
			vector <int> :: iterator it = vec2.begin();
			node[*it].cnt++;
			node[*it].num.insert(a);
			cout << node[*it].id << " ";
		}
		cout << endl;
	}
	return 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
*/

标签:node,map,CSP202203,int,read,vec,节点
From: https://www.cnblogs.com/kevin-chance/p/16735611.html

相关文章

  • CSP202203_2
    CSP202203_2目录CSP202203_2题目思路暴力差分Code题目出行计划思路暴力针对每一次的q询问,遍历所有场所判断是否可行。由于场所的计划到达时间t升序给出,因此可以......