zoukankan      html  css  js  c++  java
  • noi.ac #546 分组

    题目链接:戳我

    题目描述

    现在有n个字符串,你需要从中选出一些字符串,使得选出的字符串能被分组,满足每组大小为2,且可以从每组选出该组的两个字符串的一个非空公共后缀,使得每组选出的串互不相同。

    输入格式

    第一行一个整数n。
    接下来n行,每行一个字符串。

    输出格式

    输出一个整数,表示答案。

    样例输入

    2
    TARPOL
    PROL

    样例输出

    2

    数据范围

    对于所有数据,1≤n≤5000,|Si|≤50,其中|Si| 表示输入的第i个字符串的长度。
    时间限制 1s1s ,空间限制 512MB。
    subtask1(20pts):n≤2。
    subtask2(20pts):n≤6。
    subtask3(20pts):n≤10。
    subtask4(20pts):n≤100。
    subtask5(20pts): 无特殊限制。

    把所有的串反过来,建字典树。然后每一个节点最多取2个,从深到浅贪心即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define MAXN 5010
    int n,tot,len;
    int f[MAXN*55],ch[MAXN*55][27];
    char s[55];
    inline void dfs(int x)
    {
    	for(int i=0;i<26;i++)
    	{
    		if(ch[x][i]) 
    			dfs(ch[x][i]),f[x]+=f[ch[x][i]];
    	}
    	if(x&&f[x]>=2) f[x]-=2;
    }
    int main()
    {
    	#ifndef ONLINE_JUDGE
    	freopen("ce.in","r",stdin);
    	#endif
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",s+1);
    		len=strlen(s+1);
    		int now=0;
    		for(int j=len;j>=1;j--)
    		{
    			if(!ch[now][s[j]-'A']) ch[now][s[j]-'A']=++tot;
    			now=ch[now][s[j]-'A'];
    		}
    		f[now]++;
    	}
    	dfs(0);
    	printf("%d
    ",n-f[0]);
    	return 0;
    }
    
  • 相关阅读:
    590. N 叉树的后序遍历
    CF605E
    网络流水题题单
    wqs二分的边界
    luoguP6326 Shopping
    【THUWC2020】工资分配
    CF1336简要题解
    「PKUWC2020」最小割
    洛谷P4895 独钓寒江雪
    省选联考2020简要题解
  • 原文地址:https://www.cnblogs.com/fengxunling/p/11163866.html
Copyright © 2011-2022 走看看