• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
天梯赛-千手观音

7-4 千手观音

思路

给定一个从小到大的顺序,通过这个顺序来得到每个位次的关系。

对于给定顺序有以下两种关系:

  1. 位数不同,不能得到关系
  2. 位数相同,通过进行比较,前n位(高位到低位),若在第n+1位出现不同,那么能够推出第n+1位的两个数的大小关系

​ 因此我们可以依次来建立有向无环图,若a, b,则建立边<a, b>, 通过拓扑排序我们可以得到一个排序的大小关系,另外对于不能得出关系的可以进行字典序比较,所以我们在拓扑排序的时候应该用优先队列,小的string先进去,另一个需要注意的是,每个点的关系并不一定能得到,如果该字符串没有在字典里面,需要加进去(保证所有字符串都能够输出)

这个题有点卡常,不要使用#include <bit/stdc++.h>, 能开优化的尽量优化,字典用unrodered_map, 查询O(1)

Code

#include <queue>
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
using namespace std;

const int N = 1e5 + 10;

vector<vector<string>> v;

unordered_map<string, int> en;

bool f1;

unordered_map<string, vector<string>> g;

void bfs() {
    priority_queue<string, vector<string>, greater<string>> q1;
    for (auto &x: en) {
        if (!x.second) {
            q1.push(x.first);
        }
    }
    while (q1.size()) {
        string t = q1.top(); q1.pop();
        if (f1 != false)
            cout << ".";
        else
            f1 = true;
        cout << t;
        for (auto &x: g[t]) {
            if (!--en[x]) {
                q1.push(x);
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    int n; cin >> n;

    auto act = [](vector<string> &a, vector<string> &b) {
        if (a.size() != b.size()) return;
        for (int i = 0; i < a.size(); i ++) {
            if (a[i] == b[i]) continue;
            g[a[i]].push_back(b[i]);
            en[b[i]] ++;
            break;
        }
    };

    auto init = [](string &b) {
        vector<string> t;
        string s1;
        for (int i = 0; i < b.size(); i ++) {
            if (b[i] == '.') {
                t.push_back(s1);
                if (!en.count(s1)) en[s1] = 0;
                s1.clear();
            } else {
                s1.push_back(b[i]);
            }
        }
        if (s1.size()) {
            if (!en.count(s1)) en[s1] = 0;
            t.push_back(s1);
        }
        v.push_back(t);
    };

    for (int i = 1; i <= n; i ++) {
        string t; cin >> t; 
        init(t);
        if (i != 1) {
            int k = v.size();
            act(v[k - 2], v[k - 1]);
        }
    }
    
    bfs();
}
posted on 2022-12-28 12:42  Jack404  阅读(58)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3