Java教程

2022春每日一题:Day 32

本文主要是介绍2022春每日一题:Day 32,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目:[USACO12DEC]First! G

不太记得当时怎么想的了,但是显然,当一个字符串的前缀存在则他一定不是first,然后做法:对于每个字符串,把每个字符结尾跟他有相同前缀的单词的同元素建边,保证这个元素严格大于其他元素,然后判环,有环的话说明不能是first,反之则是。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <iostream>
const int N=3e4+5,M=3e5+5;
using namespace std;
int n,m,tot,num,ss[N],vis[N],rd[26];
string s,dic[N];
vector <int> g[26];
namespace trietree
{
	struct trie
	{
		int son[26],tag;
	}e[M];
	void insert(int len)
	{
		int p=0;
		for(int i=0;i<len;i++)
		{
			int k=s[i]-'a';
			if(!e[p].son[k])
			    e[p].son[k]=++tot;
			p=e[p].son[k];
		}
		e[p].tag=1;
	}
	bool topusort()
	{
		queue <int> q;
		while(!q.empty())
		    q.pop();
		int cnt=0;
		for(int i=0;i<26;i++)
		    if(!rd[i])
		        q.push(i);
		while(!q.empty())
		{
			int now=q.front();
			int len=g[now].size();
			++cnt;
			q.pop();
			for(int i=0;i<len;i++)
			{
				int k=g[now][i];
				--rd[k];
				if(!rd[k])
				    q.push(k);
			}
		}
		return cnt==26;
	}
	void clear(int len,int id)
	{
		int p=0,ok=0;
		s=dic[id];
		for(int i=0;i<26;i++)
		    g[i].clear(),rd[i]=0;
		for(int i=0;i<len;i++)
		{
			if(e[p].tag)
			    ok=1;
			int k=s[i]-'a';
			for(int j=0;j<26;j++)
			    if(j!=k && e[p].son[j])
			        g[k].push_back(j),rd[j]++;
			p=e[p].son[k];
		}
		if(!topusort())
		    ok=1;
		if(ok)
		    vis[id]=1;
		num+=ok;
	}
}
using namespace trietree;
int main()
{
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>s;
		ss[i]=s.length();
		dic[i]=s;
		insert(ss[i]);
	}
	for(int i=1;i<=n;i++)
	    clear(ss[i],i);
	cout<<n-num<<'\n';
	for(int i=1;i<=n;i++)
	    if(!vis[i])
	        cout<<dic[i]<<'\n';
	return 0;
}
这篇关于2022春每日一题:Day 32的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!