• P6286 [COCI20162017#1] Cezar


    这个题好难 真的好难

    对拓扑排序不是很熟练 但是能明显感觉到强烈的先后顺序 但是就是建不了边

    因为这个题要求最后的目标顺序 那我们就按照他的目标顺序进行插入字典树

    这样的好处就是 已经在字典树里面同层的点一定是要在现在插入点前面出现的

    前缀这个点太容易忽略了 不过题目还算良心 只有两个点有前缀 要是每个点都有前缀 那真的就暴毙了

    点击查看代码
    #include<bits/stdc++.h>
    using namespace std;
    #define lowbit(x) x&(-x)
    #define ll long long
    const int maxn=1e5+5;
    bool pd=true;
    int tr[maxn][26];
    int n,cnt,tt;
    int num[maxn],inn[maxn],ans[maxn];
    vector<int>Q[maxn];
    void insert(string ss);
    string s[105];
    queue<int>q;
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++)cin>>s[i];
    	for(int i=1;i<=n;i++)cin>>num[i],insert(s[num[i]]);
    	if(!pd){
    		cout<<"NE"<<endl;
    		return 0;
    	}
    	for(int i=0;i<26;i++)
    	if(!inn[i])q.push(i);//
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		if(ans[u]){
    			cout<<"NE"<<endl;
    			return 0;
    		}
    		ans[u]=++tt;
    		for(int i=0;i<Q[u].size();i++){
    			int to=Q[u][i];
    			inn[to]--;
    			if(!inn[to])
    			q.push(to);
    		}
    	}
    	for(int i=0;i<26;i++)
    	if(inn[i]){
    		cout<<"NE"<<endl;
    		return 0;
    	}
    	cout<<"DA"<<endl;
    	char c;
    	for(int i=0;i<26;i++){
    		if(!ans[i])ans[i]=++tt;
    		c=ans[i]-1+'a';
    		cout<<c;
    	}
    	cout<<endl;
    	return 0;
    }
    void insert(string ss){
    	int root=0;
    	for(int i=0;i<ss.size();i++){
    		int id=ss[i]-'a';
    		if(!tr[root][id])tr[root][id]=++cnt;
    		for(int i=0;i<26;i++)
    		if(i!=id&&tr[root][i])Q[i].push_back(id),inn[id]++;
    		root=tr[root][id];
    	}
    	for(int i=0;i<26;i++)
    	if(tr[root][i]){
    		pd=false;
    		return ;
    	}
    }
    
  • 相关阅读:
    观察者模式 java实现
    Decorator 模式
    Adapter 模式 java 实现
    Singleton 模式 Java,c++实现
    抽象工厂 java实现
    工厂方法模式 java实现
    简单工厂模式 Java实现
    【4】学习JS 数据结构与算法笔记
    【3】JavaScript编程全解笔记(三)
    【3】如何高效学习笔记
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/16087337.html
Copyright © 2020-2023  润新知