【题解】AT_abc298_c 题解

AT_abc298_c 题解

思路分析

看到题解区里的各位大佬都直接上 set 和 multiset,我这里说一个用两组 set 和一组 map 的算法。

首先,题目要求记录哪些盒子装了某个数并要求升序去重输出。这个简单,用一组 set 记录每个数装在的盒子,然后每装一次,设把 xx 装进 yy,那么就将 yy 往第 xx 个 set 里面装,然后每次询问直接输出即可。

其次,对于另外一种询问,要求求出盒子里面装了哪些数并要求升序排序。我们可以参照上述的思路,把数存进一组 set 里面。但是,set 会自动去重,所以还要再开一组 map,记录每个盒子里面的每个数的出现次数。在操作放入时,设把 xx 装进 yy,那么就将 xx 往第 yy 个 set 里面装,同时让第 yy 个 map 中 xx 项的值加一。在询问输出时,先遍历所有数,然后对于每个数,重复输出相应次数次就可以了。

依照上述步骤实现即可。

关键代码

set <int> a[N]; //用于记录哪些盒子装了某个数的 set
set <int> b[N]; //用于记录盒子里面装了哪些数的 set
map <int, int> ca[N];//用于记录每个盒子里面的每个数的出现次数的 map

int main()
{
	int n, q;
	cin >> n >> q;
	while(q--)
	{
		int op;
		cin >> op;
		if(op == 1) //插入操作
		{
			int x, y;
			cin >> x >> y;
			a[y].insert(x); //记录盒子里面装了哪些数:将 x 往第 y 个 set 里面装
			ca[y][x]++; //记录次数
			b[x].insert(y); //记录哪些盒子装了某个数:将 y 往第 x 个 set 里面装
		}
		if(op == 2) 
		{
			int g;
			cin >> g; 
			for(auto i = a[g].begin();i != a[g].end();i++) //先遍历所有数
			{
				int p = *i; //根据迭代器获取值
				for(int j = 1;j <= ca[g][p];j++) //对于每个数,重复输出相应次数次
				{
					cout << p << " ";
				}
			}
			cout << endl;
		}
		if(op == 3) //哪些盒子装了某个数
		{
			int g;
			cin >> g; 
			for(auto i = b[g].begin();i != b[g].end();i++) //直接遍历输出
			{
				int p = *i; //根据迭代器获取值
				cout << p << " ";
			}
			cout << endl;
		}
	}
	return 0;
}
posted @ 2023-04-17 23:30  邻补角-SSA  阅读(10)  评论(0)    收藏  举报  来源