codeforces D. Secret Passwords

题目链接:codeforces D. Secret Passwords

题目要求

One unknown hacker wants to get the admin’s password of AtForces testing system, to get problems from the next contest. To achieve that, he sneaked into the administrator’s office and stole a piece of paper with a list of nn passwords — strings, consists of small Latin letters.

Hacker went home and started preparing to hack AtForces. He found that the system contains only passwords from the stolen list and that the system determines the equivalence of the passwords aa and bb as follows:

two passwords aa and bb are equivalent if there is a letter, that exists in both aa and bb;
two passwords aa and bb are equivalent if there is a password cc from the list, which is equivalent to both aa and bb.
If a password is set in the system and an equivalent one is applied to access the system, then the user is accessed into the system.

For example, if the list contain passwords “a”, “b”, “ab”, “d”, then passwords “a”, “b”, “ab” are equivalent to each other, but the password “d” is not equivalent to any other password from list. In other words, if:

admin’s password is “b”, then you can access to system by using any of this passwords: “a”, “b”, “ab”;
admin’s password is “d”, then you can access to system by using only “d”.
Only one password from the list is the admin’s password from the testing system. Help hacker to calculate the minimal number of passwords, required to guaranteed access to the system. Keep in mind that the hacker does not know which password is set in the system.

Input
The first line contain integer nn (1≤n≤2⋅1051≤n≤2⋅105) — number of passwords in the list. Next nn lines contains passwords from the list – non-empty strings sisi, with length at most 5050 letters. Some of the passwords may be equal.

It is guaranteed that the total length of all passwords does not exceed 106106 letters. All of them consist only of lowercase Latin letters.

Output
In a single line print the minimal number of passwords, the use of which will allow guaranteed to access the system.

Examples
input
4
a
b
ab
d
output
2
input
3
ab
bc
abc
output
1
input
1
codeforces
output
1
Note
In the second example hacker need to use any of the passwords to access the system.

解题思路

这个题运用了并查集算法,具体的并查集算法怎么理解,请看大佬的解答:5分钟学会并查集算法
并查集算法理解起来不难,但我在做题应用的时候发现,难点出现在怎么对输出的int型、string型、char型数据进行加工,适应并查集的套路。
例如这一题,char型数组,怎么找到分层的par[]数组呢?分析题意后发现,只要分最大26层就行了,因为26个英文字母,输入1行,最多覆盖26个英文字母。所以我把par[]定义为了一个26列的数组。
以input
4
a ////s=a,a[1]=1, par[1]=1
b ////s=b,a[1]=1,a[2]=1, par[1]=2,par[2]=2
ab //s=b,a[1]=1,a[2]=1, par[1]=2,par[2]=2
d ////s=d,a[1]=1,a[2]=1,a[4]=1, par[1]=2,par[2]=2,par[3]=3,par[4]=4…
output
2
第一遍代码没有把问题想透,以至于反复提交4次,所以下次做这种题,应该仔细想想符合题意的输出都有哪些特点,怎样正确找到答案。

正确答案

#include <iostream>
#include<bits/stdc++.h>

using namespace std;
#define ll long long
const int maxn=2e5+7;
int par[50];//用来存当前树节点的父节点,相当于上级
char s[55];

int findn(int x){
    if(par[x]==x) //自己就是掌门
        return par[x];
    else
        return par[x]=findn(par[x]); //递归,直到找到掌门为止
}

int main()
{
    int t;
    cin>>t;
    bool a[30];
    int num=0;
    for(int i=1;i<=26;i++)a[i]=false;
    for(int i=1;i<=26;i++){
        par[i]=i;  //先让所有节点为单个节点;
    }
    while(t--){
        cin>>s;
        int le=strlen(s);
        for(int i=0;i<le-1;i++){
                a[s[i]-'a'+1]=true;
                int m=findn(s[i]-'a'+1);
                int n=findn(s[i+1]-'a'+1);
                if(m!=n)//门派不同,把前面的数字变为后面的数字
                    par[m]=n;

        }a[s[le-1]-'a'+1]=true;
    }
        for(int i=1;i<=26;i++)
            if(a[i]&&findn(i)==i)
                ++num;
    cout<<num<<endl;
    for(int i=1;i<=26;i++){
        printf("%d ",par[i]);
    }
    printf("\n");
    for(int i=1;i<=26;i++){
        printf("%d ",a[i]);
    }
    return 0;
}
发布了36 篇原创文章 · 获赞 1 · 访问量 1410

猜你喜欢

转载自blog.csdn.net/atnanajiang/article/details/103468911