首页 > 其他分享 >[atcoder]【LCR114] [

[atcoder]【LCR114] [

时间:2024-05-04 09:22:06浏览次数:27  
标签:atcoder ch LCR114 int char arrayDeque boolean new


import java.util.*;

class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        String str = solution.alienOrder(new String[]{
                "wrt", "wrf", "er", "ett", "rftt"
        });
        System.out.println(str);
    }

    public String alienOrder(String[] words) {
        for (int i = 0; i < 26; i++) {
            children[i] = new ArrayList<>();
            parent[i] = new ArrayList<>();
        }
        int p = -1;
        for (int i = 0; i < words.length && valid; i++) {
            char ch = words[i].charAt(0);
            if (p != -1 && p != ch - 'a') {
                addEdge((char)(p+'a'), ch);
            } else {
                // do nothing since no parent
            }
            p = ch - 'a';
        }
        for (int i = 0; i < words.length && valid; i++) {
            build(words[i]);
        }
        String str = bfs();
        return str;
    }

    public String bfs() {
        if (!valid) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        boolean[] visited = new boolean[26];
        ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 26; i++) {
            if (children[i].isEmpty() && dict[i]) {
                arrayDeque.add(i);
                visited[i] = true;
                list.addFirst(i);
            }
        }
        while (!arrayDeque.isEmpty()) {
            int curr = arrayDeque.poll();
            for (int p : parent[curr]) {
                if (!visited[p]) {
                    arrayDeque.add(p);
                    visited[p] = true;
                    list.addFirst(p);
                }
            }
        }
        boolean[] used = new boolean[26];
        while(!list.isEmpty()) {
            int curr = list.poll();
            sb.append((char)(curr+'a'));
            used[curr] = true;
        }
        for (int i = 0; i<26;i++){
            if(dict[i] && !used[i]) {
                sb.append((char)(i+'a'));
            }
        }
        return sb.toString();
    }

    public void build(String str) {
        TrieNode curr = dummy;
        for (int j = 0; j < str.length() && valid; j++) {
            char ch = str.charAt(j);
            curr.addChild(ch);
            curr = curr.getChild(ch);
            dict[ch - 'a'] = true;
        }
    }

    boolean[] dict = new boolean[26];
    TrieNode dummy = new TrieNode(' ');
    List<Integer>[] parent = new ArrayList[26];
    List<Integer>[] children = new ArrayList[26];

    /**
     * ch1 是ch2的祖先
     *
     * @param ch1
     * @param ch2
     * @return
     */
    boolean isAncestor(char ch1, char ch2) {
        boolean[] visited = new boolean[26];
        ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
        arrayDeque.add(ch1 - 'a');

        visited[ch1 - 'a'] = true;
        while (!arrayDeque.isEmpty()) {
            int curr = arrayDeque.poll();
            if (curr == ch2 - 'a') {
                return true;
            }
            for (int child : children[curr]) {
                if (!visited[child]) {
                    arrayDeque.add(child);
                    visited[child] = true;
                }
            }
        }
        return false;
    }

    boolean valid = true;

    public void addEdge(char parentCh, char ch){
        if (ch == parentCh) {
            // 祖先节点和子节点一样,则不需要
        } else if (isAncestor(ch, parentCh)) {
            valid = false;
        }
        // 否则
        else if (isAncestor(parentCh, ch)) {
            // 关系已经存在, 忽略
        } else {
            // 加一个关系
            children[parentCh].add(ch - 'a');
            parent[ch - 'a'].add(parentCh - 'a');
        }
    }
    class TrieNode {
        char ch;
        TreeMap<Integer, TrieNode> map = new TreeMap<>();

        public void addChild(char ch) {
            TrieNode parentNode = map.lastEntry() != null ? map.lastEntry().getValue() : null;
            // add a trie node;
            TrieNode node = getChild(ch);
            if (node != null) {
                return;
            }
            node = new TrieNode(ch);
            map.put(ch - 'a', node);
            // 构建图关系
            if (map.size() == 1) {
                //没有关系,忽略
            } else {
                // 构建关系
                addEdge(parentNode.ch, ch);
            }
        }

        public TrieNode getChild(char ch) {
            return map.get(ch - 'a');
        }

        public TrieNode(char ch) {
            this.ch = ch;
            map = new TreeMap<>();
        }
    }

}

标签:atcoder,ch,LCR114,int,char,arrayDeque,boolean,new
From: https://www.cnblogs.com/fishcanfly/p/18171988

相关文章

  • [atcoder 351] [F Double Sum] [线段树]
    解法,使用线段树。请看代码:importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.math.BigInteger;importjava.util.StringTokenizer;publicclassMain{staticclassSegmentNode{intleft;......
  • Atcoder ABC 351 全题解
    乾岩我:G题来咯!!!大火:这G题,大家都不敢做,说是有人在里面放了毒瘤。我:做,做,为什么不做!不做也别想活着!!!(两天后)我:我的G题完成辣!!!!!!AB不讲C显然$2^a*2=2^{a+1}$。考虑用一个栈存球的大小是$2$的多少次方,每次插入球后,不断取出后面两个球,大小相同则合并,否则插入下一个......
  • AtCoder-abc350_g 题解
    原题链接题意简述有一个无向图,初始时没有边。接下来有一些操作:将\(u,v\)连边。询问\(u,v\)的距离是否为\(2\),如果是,则输出中间的那个点的编号,否则输出0。每次询问后,更新\(lastans\)为询问的答案,初始时为\(0\)。每次操作的\(opt,u,v\)使用\(lastans\)解码,......
  • AtCoder-abc350_f 题解
    原题链接题意简述给定一个字符串\(S\),对于每个匹配的括号,将括号内的字符左右翻转并大小写反转,然后删除括号。输出最后的序列。思路本题为文艺平衡树的模板题。扫一遍字符串进行括号匹配,每次把最内层的括号进行操作。最后遍历一遍平衡树,将不为括号字符的字符输出。FHQ_Treap......
  • AtCoder Beginner Contest 351
    B-SpottheDifference难度:⭐题目大意给定两个矩阵,找不同解题思路数据很小,暴力就行;神秘代码#include<bits/stdc++.h>#defineintunsignedlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#defineendl'\n'usingnamespa......
  • AtCoder-abc351_f讲解
    原题翻译给定一个序列\(A\),求出:\[\sum\limits_{i=1}^N\sum\limits_{j=i+1}^N\max(A_j-A_i,0)\]答案小于\(2^{63}\)。思路这里提供三种思路(分块经XXR尝试,卡常卡不过):1权值树状数组将\(A\)离散化,设\(rk_i\)为\(A_i\)离散化后的排名,去重后元素个数为\(M\)。每......
  • AtCoder-abc351_d 题解
    原题翻译题意简述给定\(H\timesW\)的网格图,如果一个字符是#,则不能走到该字符上;如果是.,则可以走到该字符上,但如果它周围\(4\)个格子中有#字符,则不能再继续行走了。自由度是指从一个格子出发,能走到不同格子的数量(可以出发多次)。求出所有格子的最大自由度。思路考虑......
  • AtCoder Beginner Contest 208 E
    E-DigitProducts点击查看代码map<int,int>f[20];voidsolve(){intn,k;cin>>n>>k;autos=to_string(n);intm=s.size();function<int(int,int,int,int)>dfs=[&](inti,intlimit,intis_num,intmul)->int{if(i......
  • AtCoder Beginner Contest 351 E - Jump Distance Sum 切比雪夫距离与曼哈顿距离的转
    先说知识点。曼哈顿距离:横纵坐标距离差的绝对值的和,即|X1-X2|+|Y1-Y2|,离(0,0)点曼哈顿距离为1的点形成的是一个旋转45度后的正方形切比雪夫距离:横纵坐标距离差的绝对值的最大值,即max(|X1-X2|,|Y1-Y2|),离(0,0)点切比雪夫距离为1的点形成的是一个不旋转的正方形曼哈......
  • atcoder集
    AtCoderBeginnerContest351A-Thebottomoftheninth(签到题) Code:#include<bits/stdc++.h>usingnamespacestd;#definedebug(x)cerr<<#x<<":"<<x<<'\n';intmain(){ios::sync_w......