• 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 ;
    	}
    }
    
  • 相关阅读:
    时间控件的操作
    Appium环境搭建
    测试常用英文词汇
    自动化测试中一段代码对应多个用例
    Linux常见命令
    元素的操作的简谈
    eclipse代码编辑界面代码块收缩的实现
    关键字驱动和数据驱动
    uni-app中如何判断浏览器内核
    JS实现 图片放大镜功能
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/16087337.html
Copyright © 2020-2023  润新知