【算法】【stl】

0 阅读2分钟

Simons and Posting Blogs


题目大意

发布一篇博客时,会按顺序处理博客里提到的用户:

  • 如果这个用户已经在 当前队列 QQ 里,就把它移动到 QQ 的最前面(“提到”一次,相当于“激活”一下它)。
  • 如果这个用户不在 QQ 里,就把它插入到 QQ 的最前面。

我们要选择 博客发布的顺序,使得最终 QQ 的字典序最小。

代码

#include <bits/stdc++.h>  
using namespace std;  
using ll=long long;  
void so(){  
    int n;cin>>n;  
    vector<vector<int>>a(n,vector<int>{});  
    for(int i=0;i<n;i++){  
        int l;cin>>l;  
        set<int>st;  
        for(int j=0;j<l;j++){  
            int x;cin>>x;a[i].push_back(x);  
        }reverse(a[i].begin(),a[i].end());  
        vector<int>rep;  
        for(int j=0;j<l;j++){  
            if(st.empty()||st.find(a[i][j])==st.end()){  
                rep.push_back(a[i][j]);  
                st.insert(a[i][j]);  
            }  
        }a[i]=rep;  
    }sort(a.begin(),a.end());  
    vector<int>ans;  
    map<int,int>seen;  
    while(true){  
        if(a.empty())break;  
        for(int i:a[0]){  
            if(seen[i]==0){  
                seen[i]=1;  
                ans.push_back(i);  
            }  
        }vector<vector<int>>repp;  
        for(int i=1;i<a.size();i++){  
            vector<int>rep;  
            for(int j=0;j<a[i].size();j++){  
                if(!seen[a[i][j]])rep.push_back(a[i][j]);  
            }repp.push_back(rep);  
        }a=repp;  
        sort(a.begin(),a.end());  
    }  
    for(int i:ans){cout<<i<<' ';}  
    cout<<'\n';  
}int main(){  
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);  
    int t;cin>>t;  
    while(t--){so();}  
}

思路

1.总体思路:把b[i]逆序后排序,字典序小的优先出现,然后去掉已经出现过的,重复这一过程(由数据大小知)

stl

1. set

set<int> st;
st.empty()
st.find(a[i][j]) == st.end()
st.insert(a[i][j])
  • 有序集合,元素不重复,自动排序(默认升序)。
  • st.empty():判断集合是否为空。
  • st.find(x):查找 x,返回迭代器,如果没找到返回 st.end()
  • st.insert(x):插入元素,如果已存在则插入失败(但这里没检查返回值)。

在这里用于 去除同一篇博客内重复的用户(只保留第一次出现的)。


2. map

map<int,int> seen;
seen[i] == 0
seen[i] = 1
  • 键值对映射,自动按键排序。
  • map<int,int> 的键是用户 ID,值是标记(0 未出现,1 已出现)。
  • seen[i]:如果键 i 不存在,会默认初始化为 0(因为 int 的默认构造是 0)。
  • 用来标记一个用户是否已经被加入最终答案。

3. sort

sort(a.begin(), a.end());
  • 排序算法,默认升序。
  • vector<vector<int>> 排序时,按字典序比较两个 vector<int>
  • 这里用于每次循环后重新排序剩余博客,保证每次取第一个博客(即当前字典序最小的博客)来处理。