参照紫书书写,无法通过样例,码风清晰

UVA12096 The SetStack Computer

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));
}

|