Prosecutor_Godot_ @ 2024-02-12 21:27:46
rt,基本思路与主程序参照紫书,将set<int>
与ID
进行映射,
使用宏定义了全部内容迭代器
#define ALL(x) x.begin(),x.end()
和插入迭代器
#define INS(x) inserter(x,x.begin())
,
利用了STL的内建集合运算函数。
#include<bits/stdc++.h>
#define ALL(x) x.begin(),x.end() //对“全部内容”的迭代器
#define INS(x) inserter(x,x.begin())//插入迭代器
using namespace std;
typedef set<int> Set;//!!!定义一个可操作的集合类型,可以存在映射
map<Set,int> IDbook;//集合对ID的映射
vector<Set> Setbook;//ID对集合的映射
vector<int> Stack;//总栈,也是ID对集合的映射
//分配ID
int ID(Set x){
if(IDbook.count(x)) return IDbook[x];//寻找指定的key的映射元素数量
//不存在就创建新集合
Setbook.push_back(x);
return IDbook[x]=Setbook.size()-1;
}
int N,n;
string order;
void mainFunction(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> order;
if(order=="PUSH") Stack.push_back(ID(Set())); //把一个新建的空集合放入总栈+分配ID
else if(order=="DUP") Stack.push_back(Stack.back());//实际上,“集合”不一定是一个实例,可以是一个"家族"
//剩下的所有操作都要出栈两个集合
else{
Set x1=Setbook[Stack.back()];Stack.pop_back();
Set x2=Setbook[Stack.back()];Stack.pop_back();
Set x;//接下来要操作的大集合
if(order=="UNION") set_union(ALL(x1),ALL(x2),INS(x));//!!!STL内建集合运算函数
else if(order=="INTERSECT") set_intersection(ALL(x1),ALL(x2),INS(x));//同上
else if(order=="ADD") x=x2;x.insert(ID(x1));//ID的意义:对集合进行抽象化
Stack.push_back(ID(x));
}
cout << Setbook[Stack.back()].size() << '\n';
}
return;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> N;
for(int i=1;i<=N;i++){
mainFunction();
cout << "***\n";
//清栈
IDbook.clear();Setbook.clear();Stack.clear();
}
return 0;
}
上述程序输入样例#1后输出为
0
0
1
0
1
1
2
2
3
***
0
0
1
0
1
***
同样,udebug中的样例也无法通过。
by AlexandreLea @ 2024-02-12 23:54:46
@ProsecutorGodot 在最关键的进行末三种操作(UNION,INTERSECT和ADD)时,你直接将集合拉下来操作。
但是,因为修改后的东西有一项 ADD 操作,需要把两个集合并(不是并集)起来,需要操作的对象是集合编号,因此需要用集合编号来进行。
具体的你可以看我的代码:
else
{
int a = stk.top();
stk.pop();
int b = stk.top();
stk.pop();
set<int> st;
if (op == "UNION")
set_union(rcnv[a].begin(), rcnv[a].end(), rcnv[b].begin(), rcnv[b].end(), inserter(st, st.begin()));
else if (op == "INTERSECT")
set_intersection(rcnv[a].begin(), rcnv[a].end(), rcnv[b].begin(), rcnv[b].end(), inserter(st, st.begin()));
else if (op == "ADD")
{
st = rcnv[b];
st.insert(a);
}
stk.push(getid(st));
}