【题解】AT_abc298_c 题解
AT_abc298_c 题解
思路分析
看到题解区里的各位大佬都直接上 set 和 multiset,我这里说一个用两组 set 和一组 map 的算法。
首先,题目要求记录哪些盒子装了某个数并要求升序去重输出。这个简单,用一组 set 记录每个数装在的盒子,然后每装一次,设把 装进 ,那么就将 往第 个 set 里面装,然后每次询问直接输出即可。
其次,对于另外一种询问,要求求出盒子里面装了哪些数并要求升序排序。我们可以参照上述的思路,把数存进一组 set 里面。但是,set 会自动去重,所以还要再开一组 map,记录每个盒子里面的每个数的出现次数。在操作放入时,设把 装进 ,那么就将 往第 个 set 里面装,同时让第 个 map 中 项的值加一。在询问输出时,先遍历所有数,然后对于每个数,重复输出相应次数次就可以了。
依照上述步骤实现即可。
关键代码
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;
}

浙公网安备 33010602011771号